解题:POI 2006 PRO-Professor Szu

题面

这个题是比较套路的做法啦,建反图后缩点+拓扑排序嘛,对于所有处在$size>=2$的SCC中的点都是无限解(可以一直绕)

然后注意统计的时候的小细节,因为无限解/大解也要输出,所以我们把这些点统一统计成36501,然后所有的方案都对36501取min就可以很方便的输出了

 1 #include<cstdio>
 2 #include<vector>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N=1000005,INF=36501;
 7 int P[N],Noww[N],Goal[N];
 8 int p[N],noww[N],goal[N];
 9 int dfn[N],low[N],col[N],deg[N],inf[N];
10 int stk[N],ins[N],que[N],outp[N],dp[N];
11 int n,m,c,f,b,t1,t2,cnt,Cnt,tot,top,ans;
12 void link(int f,int t)
13 {
14     noww[++cnt]=p[f];
15     goal[cnt]=t,p[f]=cnt;
16 }
17 void relink(int f,int t)
18 {
19     Noww[++Cnt]=P[f];
20     Goal[Cnt]=t,P[f]=Cnt;
21 }
22 void Tarjan_SCC(int nde)
23 {
24     dfn[nde]=low[nde]=++tot;
25     stk[++top]=nde,ins[nde]=true;
26     for(int i=p[nde];i;i=noww[i])
27         if(!dfn[goal[i]]) 
28             Tarjan_SCC(goal[i]),low[nde]=min(low[nde],low[goal[i]]);
29         else if(ins[goal[i]])
30             low[nde]=min(low[nde],low[goal[i]]);
31     if(dfn[nde]==low[nde])
32     {
33         c++; int tmp;
34         do
35         {
36             tmp=stk[top--];
37             ins[tmp]=false;
38             col[tmp]=c;
39         }while(nde!=tmp);
40     }
41 }
42 int main ()
43 {
44     scanf("%d%d",&n,&m),b=-1;
45     for(int i=1;i<=m;i++)
46         scanf("%d%d",&t1,&t2),link(t2,t1);
47     for(int i=1;i<=n+1;i++)
48         if(!dfn[i]) Tarjan_SCC(i);
49     for(int i=1;i<=n+1;i++)
50         for(int j=p[i];j;j=noww[j])
51             if(col[i]!=col[goal[j]])
52             {
53                 relink(col[i],col[goal[j]]);
54                 deg[col[goal[j]]]++; 
55             }
56             else inf[col[i]]=true;
57     for(int i=1;i<=c;i++)
58         if(!deg[i]) que[++b]=i;
59     dp[col[n+1]]=1;
60     while(f<=b)
61     {
62         int tn=que[f++];
63         if(inf[tn]&&dp[tn]) dp[tn]=INF;
64         for(int i=P[tn];i;i=Noww[i])
65         {
66             dp[Goal[i]]=min(dp[Goal[i]]+dp[tn],INF);
67             if(!(--deg[Goal[i]])) que[++b]=Goal[i];
68         }
69     }
70     for(int i=1;i<=c;i++) ans=max(ans,dp[i]);
71     for(int i=1;i<=n;i++) 
72         if(dp[col[i]]==ans) outp[++outp[0]]=i;
73     ans>36500?printf("zawsze"):printf("%d",ans);
74     puts(""),printf("%d
",outp[0]);
75     for(int i=1;i<=outp[0];i++)
76         printf("%d ",outp[i]);
77     return 0;
78 }
View Code
原文地址:https://www.cnblogs.com/ydnhaha/p/9839528.html