题目描述
一位年过古稀的老爷爷在乡间行走 而他不想兜圈子 因为那会使他昏沉 偶然路过小A发扬助人为乐优良传统 带上地图 想知道路况是否一定使他清醒 usqwedf补充:为了让欢乐赛充满欢乐 小A还想问你一些数学作业……输入输出格式
输入格式:
一行 n m k 表示乡间共有 n 个村庄 m 条道路 接下来 m 行 每行两个整数 x y 表示 村 x -> 村 y 单向连通输出格式:
第一行 输出 Yes/No [清醒/不清醒] 第二行 若为 Yes 输出 2^k对9997取模 反之 输出 k^2输入输出样例
输入样例#1:
3 3 31 2
2 3
3 1
输出样例#1:
No9
说明
[数据范围]
对于70%的数据$1<=n<=100 1<=m<=1000 1<=k<=30$ 对于100%的数据$1<=n<=1000 1<=m<=10000 1<=k<=10^9$思路
首先明确这道题其实就是求是否有负环+快速幂。然后可以使用spfa判断负环(每次加入队列时记录一下进队的次数,如果超过了总点数$n$,那么就是有负环)。
快速幂就不多说了吧。。。
坑:输出$No$时,要求的$k^2$其实是不需要Mod的。
快速幂代码:(其实就是分类讨论的思想(手动滑稽))
1 2 3 4 5 6 7 8 9 10 11 |
#define ll long long ll Fp(ll x,ll y){ ll a=x,b=y,kk=9997; ll result=1; while(b){ if(b%2==1) result = result*x%kk; b/=2; x=x*x%kk; } return result; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
#include<bits/stdc++.h> #define ll long long using namespace std; queue<int> q; ll n,m,k; vector<int> v[1010]; ll vis[10000],dis[10000],tt[10000],ans; void spfa(ll x){ memset(vis,0,sizeof(vis)); memset(dis,63,sizeof(dis)); memset(tt,0,sizeof(tt)); dis[x]=0;vis[x]=1; q.push(x); while(!q.empty()){ ll u=q.front();q.pop();vis[u]=0; for(ll i=0;i<v[u].size();i++){ if(dis[v[u][i]]>dis[u]-1){ dis[v[u][i]]=dis[u]-1; if(vis[v[u][i]]==0){ vis[v[u][i]]=1; tt[v[u][i]]++; if(tt[v[u][i]]>=n){ ans=-1; return ; }//判负环其实就是在这里,添加tt数组统计次数 q.push(v[u][i]); } } } } } ll Fp(ll x,ll y){ ll a=x,b=y,kk=9997; ll result=1; while(b){ if(b%2==1) result = result*x%kk; b/=2; x=x*x%kk; } return result; }//快速幂 int main(){ scanf("%lld%lld%lld",&n,&m,&k); for(ll i=1;i<=m;i++){ ll x,y;scanf("%lld%lld",&x,&y);v[x].push_back(y);//读入 } for(ll i=1;i<=n;i++){ spfa(i); if(ans==-1){ puts("No"); printf("%lld\n",k*k); return 0; } } puts("Yes"); printf("%lld\n",Fp(2,k)); } |