链接: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 }