1. 程式人生 > >uva-11324-SCC+dp

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 */