uva-11324-SCC+dp

https://vjudge.net/problem/UVA-11324

给出一幅有向图,问最大能找到多少个节点,使得这些节点中任意两个节点之间都至少有一条可达路径。

找出SCC后缩点求权重最大路即可。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<map>
  5 #include<set>
  6 #include<stack>
  7 #include<deque>
  8 #include<bitset>
  9 #include<unordered_map>
 10 #include<unordered_set>
 11 #include<queue>
 12 #include<cstdlib>
 13 #include<ctype.h>
 14 #include<ctime>
 15 #include<functional>
 16 #include<algorithm>
 17 #include<bits/stdc++.h>
 18 using namespace std;
 19 #define LL long long 
 20 #define pii pair<int,int>
 21 #define mp make_pair
 22 #define pb push_back
 23 #define fi first
 24 #define se second
 25 #define inf 0x3f3f3f3f
 26 #define debug puts("debug")
 27 #define mid ((L+R)>>1)
 28 #define lc (id<<1)
 29 #define rc (id<<1|1)
 30 const int maxn=1010;
 31 const int maxm=50050;
 32 const double PI=acos(-1.0);
 33 const double eps=1e-6;
 34 const LL mod=1e9+7;
 35 LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);}
 36 LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
 37 LL qpow(LL a,LL b,LL c){LL r=1; for(;b;b>>=1,a=a*a%c)if(b&1)r=r*a%c;return r;}
 38 template<class T>
 39 void prt(T v){for(auto x:v)cout<<x<<' ';cout<<endl;}
 40 struct Edge{int u,v,w,next;};
 41 
 42 vector<int>g[maxn],g2[maxn];
 43 int f[maxn],dfn[maxn],low[maxn],scc[maxn],tot[maxn],sum=0,scc_cnt=0;
 44 stack<int>S;
 45 void dfs(int u){
 46     dfn[u]=low[u]=++sum;
 47     S.push(u);
 48     for(int v:g[u]){
 49         if(!dfn[v]){
 50             dfs(v),low[u]=min(low[u],low[v]);
 51         }else if(!scc[v]){
 52             low[u]=min(low[u],dfn[v]);
 53         }
 54     }
 55     if(dfn[u]==low[u]){
 56         ++scc_cnt;
 57         for(;;){
 58             int x=S.top();S.pop();
 59             scc[x]=scc_cnt;
 60             tot[scc_cnt]++;
 61             if(x==u)break;
 62         }
 63     }
 64 }
 65 int cal(int u){
 66     if(f[u]!=-1)return f[u];
 67     f[u]=tot[u];
 68     int maxx=0;
 69     for(int v:g2[u]){
 70         maxx=max(maxx,cal(v));
 71     }
 72     return f[u]=f[u]+maxx;
 73 }
 74 int main(){
 75     int t,n,m,i,j,u,v;
 76     cin>>t;
 77     while(t--){
 78         scanf("%d%d",&n,&m);
 79         for(i=1;i<=n;++i)g[i].clear(),g2[i].clear(),tot[i]=low[i]=dfn[i]=scc[i]=0;
 80         sum=scc_cnt=0;
 81         while(!S.empty())S.pop();
 82         while(m--){
 83             scanf("%d%d",&u,&v);
 84             g[u].pb(v);
 85         }
 86         for(i=1;i<=n;++i){
 87             if(!dfn[i]){
 88                 dfs(i);
 89             }
 90         }
 91         memset(f,-1,sizeof(f));
 92         for(u=1;u<=n;++u){
 93             for(int v:g[u]){
 94                 if(scc[u]!=scc[v]){
 95                     //cout<<scc[v]<<' '<<scc[u]<<
 96                     g2[scc[v]].pb(scc[u]);
 97                 }
 98             }
 99         }
100         int ans=0;
101         for(i=1;i<=scc_cnt;++i){
102             f[i]=cal(i);
103             if(f[i]>ans)ans=f[i];
104         }
105         cout<<ans<<endl;
106     }
107     return 0;
108 }
109 /*
110 1
111 5 5
112 1 2
113 2 3
114 3 1
115 4 1
116 5 2
117 
118 */
原文地址:https://www.cnblogs.com/zzqc/p/10077706.html