POJ3592 Instantaneous Transference tarjan +spfa

链接:http://poj.org/problem?id=3592

题意:题目大意:给定一个矩阵,西南角为出发点,每个单位都有一订价值的金矿(#默示岩石,不成达,*默示时佛门,可以达到指定单位),队#外,每个点只能向右走或向下走,并且可以反复经过一个点。如今请求得最多可以获得多大好处 。

一开始看到这个题,会以为是费用流。但是计划上是在tarjan上的。我觉得如果比赛的时候有这道题估计我也就挂了。

因为这个图大部分的点只有两个后续节点, 但是*会有更多的节点,所以说这样会产生环,因此可以吧整个图求强连通进行缩点,因为每个强连通分量重的点你是可以得到她所有的值。不管走几次,就是那么多,缩完点之后就可以构成DAG这样,就能够求出从belong[1]出发得到的最远的点。一开始逗比了,忘了出发点是左上角,而且dis的赋初值写错了。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <stdlib.h>
  6 #include <vector>
  7 #include <queue>
  8 #include <stack>
  9 #define loop(s,i,n) for(i = s;i < n;i++)
 10 #define cl(a,b) memset(a,b,sizeof(a))
 11 using namespace std;
 12 const int maxn = 2000;
 13 struct edge
 14 {
 15     int u,v,val,next;
 16 };
 17 
 18 char map[45][45];
 19 int dfn[maxn],low[maxn],belong[maxn],inst[maxn];
 20 int head[maxn];
 21 vector<edge>edges,es;
 22 int ihead[maxn];
 23 stack<int> st;
 24 int vis[maxn],dis[maxn];
 25 int dfsclock,scc,cnt;
 26 vector<int>trans;
 27 void init(int n)
 28 {
 29     int i;
 30     loop(0,i,n+1)
 31     head[i] = -1;
 32 
 33     edges.clear();
 34     es.clear();
 35     dfsclock = scc = cnt = 0;
 36     trans.clear();
 37     return ;
 38 }
 39 void addedge(int u,int v,int val)
 40 {
 41     int m;
 42     struct edge e;
 43     e.u = u;
 44     e.v = v;
 45     e.next = head[u];
 46     edges.push_back(e);
 47     m = edges.size();
 48     head[u] = m-1;
 49     return ;
 50 }
 51 void tarjan(int i)
 52 {
 53     dfn[i] = low[i] = ++dfsclock;
 54     inst[i] = 1;
 55     st.push(i);
 56 
 57     int j;
 58     edge e;
 59     for(j = head[i]; j != -1; j = e.next)
 60     {
 61 
 62         e = edges[j];
 63         int v;
 64         v = e.v;
 65         if(!dfn[v])
 66         {
 67             tarjan(v);
 68             low[i] = min(low[v],low[i]);
 69         }
 70         else if(inst[v] && dfn[v] < low[i])
 71             low[i] = dfn[v];
 72     }
 73 
 74     if(dfn[i] == low[i])
 75     {
 76         scc++;
 77         do
 78         {
 79             j = st.top();
 80             st.pop();
 81             inst[j] = 0;
 82             belong[j] = scc;
 83         }
 84         while(i != j);
 85     }
 86 }
 87 void tarjans(int n)
 88 {
 89     dfsclock = scc = 0;
 90     memset(dfn,0,sizeof(dfn));
 91     while(!st.empty())st.pop();
 92 
 93     cl(inst,0);
 94     cl(belong,0);
 95     int i;
 96     loop(1,i,n+1)
 97     {
 98         if(!dfn[i]) tarjan(i);
 99     }
100     return ;
101 }
102 int spfa(int s,int n)
103 {
104     int i,j;
105     dis[s] = 0;
106     queue<int>q;
107     q.push(s);
108     vis[s] = 1;
109     while(!q.empty())
110     {
111         int x;
112         x = q.front();
113 
114 
115         q.pop();
116         vis[x] = 0;
117         struct edge e;
118         for(i = ihead[x]; i != -1; i = e.next)
119         {
120             int v;
121 
122             e = es[i];
123             v = e.v;
124             if(dis[v] < dis[x]+e.val)
125             {
126                 dis[v] = dis[x]+e.val;
127                 q.push(v);
128                 vis[v] = 1;
129             }
130         }
131     }
132     int max = 0;
133     for(i = 1; i <= n; i++)
134     {
135         if(dis[i] > max)
136             max = dis[i];
137     }
138 
139     return max;
140 }
141 int val[maxn];
142 int main()
143 {
144     int t;
145     int n,m,k;
146     scanf("%d",&t);
147     while(t--)
148     {
149         int i,j;
150         int p;
151         p = 0;
152         scanf("%d %d",&n,&m);
153         init(n*m+5);
154         loop(0,i,n)
155         scanf("%s",map[i]);
156         int leap = 0;
157         for(i = 0; i < n; i++)
158         {
159             for(j = 0; j < m; j++)
160             {
161                 if(map[i][j] == '*')
162                     trans.push_back(i*m+j+1);
163             }
164         }
165 
166         loop(0,i,trans.size())
167         {
168             int l,r;
169             scanf("%d %d",&l,&r);
170             if(map[l][r] == '*')
171                 addedge(trans[i],l*m+r+1,0);
172             else if(map[l][r] != '#')
173                 addedge(trans[i],l*m+r+1,map[l][r]-'0');
174         }
175 
176         loop(0,i,n)
177         {
178             loop(0,j,m)
179             {
180                 if(map[i][j] != '#')
181                 {
182                     
183                 if(i+1 < n && map[i+1][j] == '*')
184                     addedge(i*m+j+1,(1+i)*m+j+1,0);
185                 else if(i+1 < n && map[i+1][j] != '#')
186                     addedge(i*m+j+1,(1+i)*m+j+1,1+map[i+1][j]-'0');
187 
188                 if(j+1 < m && map[i][j+1] == '*' )
189                     addedge(i*m+j+1,(i)*m+2+j,0);
190                 else if( j+1 < m && map[i][j+1] != '#')
191                     addedge(i*m+j+1,i*m+j+2,map[i][j+1]-'0');
192                 }
193             }
194         }
195 
196 
197         tarjans(m*n);
198         // cout<<scc<<endl;
199         cl(val,0);
200 
201         int sum;
202         sum = 0;
203         cl(vis,0);
204         memset(ihead,-1,sizeof(ihead));
205         for(i = 1; i <= m*n; i++)
206         {
207             int r,l;
208             r = (i-1)/m;
209             l = (i-1)%m;
210             if(map[r][l] != '#' && map[r][l] != '*')
211                 val[belong[i]] += map[r][l] - '0';
212         }
213 
214         for(i = 0; i < edges.size(); i++)
215         {
216             int u,v;
217             u = edges[i].u;
218             v = edges[i].v;
219             if(belong[u] != belong[v])
220             {
221                 u = belong[u];
222                 v = belong[v];
223                 struct edge e;
224                 e.u = u;
225                 e.v = v;
226                 e.val = val[v];
227                 e.next = ihead[u];
228                 es.push_back(e);
229                 int m;
230                 m = es.size();
231                 ihead[u] = m-1;
232             }
233         }
234 
235         cl(vis,0);
236         cl(dis,-1);
237         int ans;
238 
239 
240         if(scc == 1)
241             printf("%d
",val[belong[1]]);
242         else
243         {
244             ans  = 0;
245             int ansi;
246             ans = spfa(belong[1],scc);
247             printf("%d
",ans+val[belong[1]]);
248         }
249 
250     }
251     return 0;
252 }
View Code
原文地址:https://www.cnblogs.com/0803yijia/p/3243233.html