路径
在橙子国里,有 n+1 座城市,其中城市 n+1 为首都,其中有 m 条有向公路各个城市连接起
来。从每个城市 不一定能 走到首都,其中不同的定义是:每条边可以走多次,如 果走边的顺
序有一条不同即称两方式不同。
橙子国的居民想知道到达首都方式最多的城市到达首都的方法数,以及有多少个城市有这么
多方式,按照顺序输出城市编号。
如果最多不同方式超过了 36500 那么视做全部相等,方法数输出 zawsze。
输入格式
第 1 行,两个正整数,n 和 m。(n,m<=1000000)
第 2 至 m+1 行,两个正整数 u 和 v,代表存在一条城市 u 通向城市 v 的道路。
输出格式
第 1 行,一个正整数,代表到达首都方式最多的城市到达首都的方法数。
第 2 行,一个正整数 k,代表有多少个城市有这么多方式。
第 3 行,k 个正整数,代表拥有最多达到首都方式的城市编号,从小到大。
输入样例
35
12
13
23
34
34
输出样例
4
1
1
题解:
将边反过来,去掉不能到达n+1的点,然后统计入度,跑拓扑排序,注意存在环的情况(存在入度没有清0的点)
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 using namespace std; 8 const int N=1000005; 9 int gi(){ 10 int str=0;char ch=getchar(); 11 while(ch>'9' || ch<'0')ch=getchar(); 12 while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar(); 13 return str; 14 } 15 int n,m,q[N],num=0,head[N],lim=36501; 16 struct Lin{ 17 int next,to; 18 }a[N]; 19 void init(int x,int y){ 20 a[++num].next=head[x]; 21 a[num].to=y; 22 head[x]=num; 23 } 24 bool vis[N],mark[N];int f[N],st[N],top=0,mx=0,du[N]; 25 void hfs(){ 26 int t=0,x,sum=1,u;q[1]=n+1;f[n+1]=1; 27 while(t!=sum){ 28 t++;if(t==N)t-=N;x=q[t]; 29 for(int i=head[x];i;i=a[i].next){ 30 u=a[i].to; 31 f[u]+=f[x];du[u]--; 32 if(f[u]>lim)f[u]=lim; 33 if(f[u]>mx){ 34 mx=f[u]; 35 } 36 if(!du[u]){ 37 sum++;if(sum==N)sum-=N;q[sum]=u; 38 } 39 } 40 } 41 } 42 void prework(){ 43 int t=0,x,sum=1,u;q[1]=n+1;mark[n+1]=true; 44 while(t!=sum){ 45 t++;x=q[t]; 46 for(int i=head[x];i;i=a[i].next){ 47 u=a[i].to; 48 if(mark[u])continue; 49 mark[u]=true;q[++sum]=u; 50 } 51 } 52 for(int i=1;i<=n+1;i++){ 53 if(!mark[i])continue; 54 for(int j=head[i];j;j=a[j].next){ 55 du[a[j].to]++; 56 } 57 } 58 } 59 void work(){ 60 n=gi();m=gi(); 61 int x,y; 62 for(int i=1;i<=m;i++){ 63 x=gi();y=gi(); 64 init(y,x); 65 } 66 prework(); 67 hfs(); 68 for(int i=1;i<=n+1;i++){ 69 if(du[i])f[i]=lim,mx=lim; 70 } 71 if(mx>=lim)printf("zawsze\n"); 72 else printf("%d\n",mx); 73 for(int i=1;i<=n;i++){ 74 if(f[i]==mx)st[++top]=i; 75 } 76 printf("%d\n",top); 77 for(int i=1;i<=top;i++)printf("%d ",st[i]); 78 } 79 int main() 80 { 81 freopen("path.in","r",stdin); 82 freopen("path.out","w",stdout); 83 work(); 84 return 0; 85 }