poj 3160 Father Christmas flymouse【强连通 DAG spfa 】

和上一道题一样,可以用DAG上的动态规划来做,也可以建立一个源点,用spfa来做

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<stack>
  6 #include<vector>
  7 using namespace std;
  8 
  9 const int maxn = 5005;
 10 int n,m;
 11 int first[maxn];
 12 int sc[maxn],scn[maxn],low[maxn],pre[maxn];
 13 int scnt,ecnt,dfs_clock;
 14 int dp[maxn];
 15 
 16 int first1[maxn];
 17 int ecnt1;
 18 
 19 int a[maxn];
 20 int in[maxn];
 21 
 22 struct Edge{
 23     int v,next;
 24 }e[maxn*10];
 25 
 26 Edge e1[maxn*10];
 27 
 28 stack<int> S;
 29 
 30 void init(){
 31     ecnt = ecnt1 = 0;
 32     memset(first,-1,sizeof(first));
 33     memset(first1,-1,sizeof(first1));
 34     memset(dp,0,sizeof(dp));
 35 }
 36 
 37 void addedges(int u,int v){
 38     e[ecnt].v = v;
 39     e[ecnt].next = first[u];
 40     first[u] = ecnt++;
 41 }
 42 
 43 void addedges1(int u,int v){
 44     e1[ecnt1].v = v;
 45     e1[ecnt1].next = first1[u];
 46     first1[u] = ecnt1++;
 47 }
 48 
 49 void dfs(int u){
 50     low[u] = pre[u] = ++dfs_clock;
 51     S.push(u);
 52     for(int i = first[u];~i;i = e[i].next){
 53         int v = e[i].v;
 54         if(!pre[v]){
 55             dfs(v);
 56             low[u] = min(low[u],low[v]);
 57         }
 58         else if(!sc[v]) low[u] = min(low[u],pre[v]);
 59     }
 60     if(pre[u] == low[u]){
 61         scnt++;
 62         for(;;){
 63             int x = S.top();S.pop();
 64             sc[x] = scnt;
 65             scn[scnt]+= a[x];
 66             if(x == u) break;
 67         }
 68     }
 69 }
 70 
 71 void find_scc(){
 72     while(!S.empty()) S.pop();
 73     scnt = dfs_clock = 0;
 74     memset(low,0,sizeof(low));memset(pre,0,sizeof(pre));
 75     memset(sc,0,sizeof(sc));memset(scn,0,sizeof(scn));
 76     
 77     for(int i = 1;i <= n;i++) if(!pre[i]) dfs(i);
 78 }
 79 
 80 int solve(int p){
 81     if(dp[p]) return dp[p];
 82     for(int i = first1[p];~i;i = e1[i].next){
 83         int v = e1[i].v;
 84         dp[p] = max(dp[p],solve(v));
 85     }
 86     return dp[p] = dp[p] + scn[p];
 87 }
 88 
 89 int main(){
 90     int T;
 91     while(scanf("%d %d",&n,&m) != EOF){
 92         init();
 93         for(int i = 1;i <= n;i++) {
 94             scanf("%d",&a[i]);
 95             if(a[i] < 0) a[i] = 0;
 96         }
 97         for(int i = 0;i < m;i++ ){
 98             int u,v;
 99             scanf("%d %d",&u,&v);u++;v++;
100             addedges(u,v);
101         }
102         find_scc();
103         
104              memset(in,0,sizeof(in));
105         for(int u = 1;u <= n;u++){
106             for(int i = first[u];~i;i = e[i].next){
107                 int v = e[i].v;
108                 if(sc[u] != sc[v]) addedges1(sc[u],sc[v]),in[sc[v]]++;
109             }
110         }
111         
112         int ans = 0;
113         for(int i = 1;i <= scnt;i++) {
114             ans = max(ans,solve(i));
115         }
116         printf("%d
",ans);
117     }
118     return 0;
119 }
View Code
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<stack>
  6 #include<vector>
  7 #include<queue>
  8 using namespace std;
  9 
 10 const int maxn = 5005;
 11 const int INF = 1000000005;
 12 int n,m;
 13 int first[maxn];
 14 int sc[maxn],scn[maxn],low[maxn],pre[maxn];
 15 int scnt,ecnt,dfs_clock;
 16 int dp[maxn];
 17 
 18 int du[maxn];
 19 int dis[maxn];
 20 int inq[maxn];
 21 
 22 int first1[maxn];
 23 int ecnt1;
 24 
 25 struct Edge{
 26     int v,next;
 27 }e[maxn*10];
 28 
 29 Edge e1[maxn*10];
 30 
 31 stack<int> S;
 32 vector<int> g[maxn];
 33 int val[maxn],a[maxn];
 34 
 35 void init(){
 36     ecnt = ecnt1 = 0;
 37     memset(first,-1,sizeof(first));
 38     memset(val,0,sizeof(val));
 39     memset(du,0,sizeof(du));       
 40 }
 41 
 42 void addedges(int u,int v){
 43     e[ecnt].v = v;
 44     e[ecnt].next = first[u];
 45     first[u] = ecnt++;
 46 }
 47 
 48 void dfs(int u){
 49     low[u] = pre[u] = ++dfs_clock;
 50     S.push(u);
 51     for(int i = first[u];~i;i = e[i].next){
 52         int v = e[i].v;
 53         if(!pre[v]){
 54             dfs(v);
 55             low[u] = min(low[u],low[v]);
 56         }
 57         else if(!sc[v]) low[u] = min(low[u],pre[v]);
 58     }
 59     if(pre[u] == low[u]){
 60         scnt++;
 61         for(;;){
 62             int x = S.top();S.pop();
 63             sc[x] = scnt;
 64             val[scnt] += a[x];
 65             if(x == u) break;
 66         }
 67     }
 68 }
 69 
 70 void find_scc(){
 71     while(!S.empty()) S.pop();
 72     scnt = dfs_clock = 0;
 73     memset(low,0,sizeof(low));memset(pre,0,sizeof(pre));
 74     memset(sc,0,sizeof(sc));memset(scn,0,sizeof(scn));
 75     
 76     for(int i = 1;i <= n;i++) if(!pre[i]) dfs(i);
 77 }
 78 
 79 
 80 int spfa(){  
 81     memset(inq, 0, sizeof(inq));  
 82     queue<int>q;  
 83     g[0].clear();  
 84     q.push(0);  
 85     dis[0] = 0; val[0] = 0;  
 86     for(int i = 1; i <= scnt; i++){if(du[i] == 0)g[0].push_back(i); dis[i] = -INF;}  
 87     int ans = 0;  
 88     while(!q.empty()){  
 89         int u = q.front(); q.pop(); inq[u] = 0;  
 90         for(int i = 0; i < g[u].size(); i++){  
 91             int v = g[u][i];  
 92             if(dis[v] < dis[u] + val[v]){  
 93                 dis[v] = dis[u] + val[v];  
 94                 ans = max(ans, dis[v]);  
 95                 if(inq[v] == 0)inq[v] = 1, q.push(v);  
 96             }  
 97         }  
 98     }  
 99     return ans;  
100 }  
101 
102 int main(){
103     while(scanf("%d %d",&n,&m) != EOF){
104         init();
105         for(int i = 1;i <= n;i++) {
106             scanf("%d",&a[i]);
107             if(a[i] < 0) a[i] = 0;
108         }      
109         for(int i = 0;i < m;i++ ){
110             int u,v;
111             scanf("%d %d",&u,&v);u++;v++;
112             addedges(u,v);
113         }
114         find_scc();
115         for(int i = 1;i <= scnt;i++) g[i].clear();
116     
117         for(int u = 1;u <= n;u++){
118             for(int i = first[u];~i;i = e[i].next){
119                 int v = e[i].v;
120                 if(sc[u] != sc[v]) g[sc[u]].push_back(sc[v]),du[sc[v]]++;
121             }
122         }
123         printf("%d
",spfa());
124     }
125     return 0;
126 }
View Code
原文地址:https://www.cnblogs.com/wuyuewoniu/p/4700260.html