路径

在橙子国里,有 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
");
72     else printf("%d
",mx);
73     for(int i=1;i<=n;i++){
74         if(f[i]==mx)st[++top]=i;
75     }
76     printf("%d
",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 }
原文地址:https://www.cnblogs.com/Yuzao/p/7207504.html