POJ 3592 强连通缩点+spfa最长路

来源:互联网 发布:参观国家博物馆 知乎 编辑:程序博客网 时间:2024/05/15 12:53

题意:

给定n*m的地图  (从(0,0) 开始)

#代表墙,*代表传送门(能传送到的坐标在下面依次给出),数字代表宝藏数(每次经过能且仅能取走一块宝藏)

起点在(0,0), 终点任意,且每次只能↓或→,或者传送

问:

最多能拿到多少块宝藏

 

思路:因为能传送,所以会出现环形路径,那么我们把能构成的环形路径的点缩点得到一个点,并把该点权值设为 环形路径内所有的点权和。

 

对于缩点后的图,我们把每个点权值设为父边的边权

这样跑一次spfa 最长路,最远点距离就是答案。

 

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include<stdio.h>  
  2. #include<string.h>  
  3. #include<iostream>  
  4. #include<vector>  
  5. #include<queue>  
  6. using namespace std;  
  7. #define N 1700  
  8. //N为点数  
  9. #define M 10000  
  10. //M为边数  
  11. int n, m, a[N], val[N];  
  12. int idx(int x, int y){return x*m+y;}  
  13. char map[N][N];  
  14.   
  15. struct Edge{  
  16.     int from, to, nex;  
  17.     bool sign;//是否为桥  
  18. }edge[M<<1];  
  19. int head[N], edgenum;  
  20. void add(int u, int v){  
  21.     Edge E={u, v, head[u], false};  
  22.     edge[edgenum] = E;  
  23.     head[u] = edgenum++;  
  24. }  
  25.   
  26. int DFN[N], Low[N], Stack[N], top, Time;  
  27. int taj;//连通分支标号,从1开始  
  28. int Belong[N];//Belong[i] 表示i点属于的连通分支  
  29. bool Instack[N];  
  30. vector<int> bcc[N]; //标号从1开始  
  31.   
  32. void tarjan(int u ,int fa){    
  33.     DFN[u] = Low[u] = ++ Time ;    
  34.     Stack[top ++ ] = u ;    
  35.     Instack[u] = 1 ;    
  36.   
  37.     for (int i = head[u] ; i!=-1 ; i = edge[i].nex ){    
  38.         int v = edge[i].to ;    
  39.         if(DFN[v] == -1)  
  40.         {    
  41.             tarjan(v , u) ;    
  42.             Low[u] = min(Low[u] ,Low[v]) ;  
  43.             if(DFN[u] < Low[v])  
  44.             {  
  45.                 edge[i].sign = 1;//为割桥  
  46.             }  
  47.         }    
  48.         else if(Instack[v]){    
  49.             Low[u] = min(Low[u] ,DFN[v]) ;    
  50.         }  
  51.     }    
  52.     if(Low[u] == DFN[u]){    
  53.         int now ;  
  54.         taj ++ ; bcc[taj].clear();  
  55.         do{  
  56.             now = Stack[-- top] ;    
  57.             Instack[now] = 0 ;   
  58.             Belong [now] = taj ;  
  59.             bcc[taj].push_back(now);  
  60.         }while(now != u) ;  
  61.     }  
  62. }  
  63.   
  64. void tarjan_init(int all){  
  65.     memset(DFN, -1, sizeof(DFN));  
  66.     memset(Instack, 0, sizeof(Instack));  
  67.     top = Time = taj = 0;  
  68.     for(int i=0;i<all;i++)if(DFN[i]==-1 && map[i/m][i%m] != '#')tarjan(i, i); //点标从0开始  
  69. }  
  70.   
  71. vector<int>G[N];  
  72. int dis[N], D[N][N];  
  73. int spfa(){  
  74.     memset(a, 0, sizeof(a));  
  75.     memset(dis, -1, sizeof(dis));  
  76.     queue<int>q;  
  77.     q.push(Belong[0]);  
  78.     int ans = val[Belong[0]];  
  79.     dis[Belong[0]] = ans;  
  80.     while(!q.empty()){  
  81.         int u = q.front(); q.pop();  
  82.         a[u] = 0;  
  83.         for(int i = 0; i < G[u].size(); i++)  
  84.         {  
  85.             int v = G[u][i];  
  86.             if(dis[v] < dis[u] + D[u][v])  
  87.             {  
  88.                 dis[v] = dis[u] + D[u][v];  
  89.                 ans = max(ans, dis[v]);  
  90.                 if(a[v] == 0)q.push(v), a[v] = 1;  
  91.             }  
  92.         }  
  93.     }  
  94.     return max(ans, 0);  
  95. }  
  96. int main(){  
  97.     int u, v, i, j, T;scanf("%d",&T);  
  98.     while(T--){  
  99.         scanf("%d %d", &n, &m);  
  100.         memset(head, -1, sizeof(head)); edgenum = 0;  
  101.         memset(a, 0, sizeof(a)); memset(val, 0, sizeof(val));  
  102.         for(i = 0; i < n; i++)   scanf("%s",map[i]);       
  103.         for(i = 0; i < n; i++)  
  104.         {  
  105.             for(j = 0; j < m; j++)if(map[i][j] != '#')  
  106.             {  
  107.                 if(i<n-1 && map[i+1][j] != '#')add(idx(i,j), idx(i+1,j));  
  108.                 if(j<m-1 && map[i][j+1] != '#')add(idx(i,j), idx(i,j+1));  
  109.                 if(map[i][j] == '*')  
  110.                 {scanf("%d %d", &u, &v); if(map[u][v]=='#')continue;add(idx(i,j), idx(u,v));}  
  111.                 else a[idx(i,j)] = map[i][j]-'0';  
  112.             }  
  113.         }  
  114.         tarjan_init(n*m);  
  115.         for(i = 1; i <= taj; i++)for(j = 0; j < bcc[i].size(); j++)val[i] += a[bcc[i][j]];  
  116.         for(i = 1; i <= taj; i++)G[i].clear();  
  117.         for(i = 0; i < edgenum; i++){  
  118.             u =  Belong[edge[i].from]; v =  Belong[edge[i].to];  
  119.             if(u != v)  
  120.                 G[u].push_back(v),D[u][v] = val[v];  
  121.         }  
  122.         printf("%d\n", spfa());  
  123.     }  
  124.     return 0;  
  125. }  
  126. /* 
  127. 99 
  128. 2 2 
  129. 11 
  130. 1* 
  131. 0 0 
  132.  
  133. 3 3 
  134. 11# 
  135. 1*1 
  136. ##9 
  137. 0 0 
  138.  
  139. 99 
  140. 10 10 
  141. 1167811678 
  142. 1*77811678 
  143. 1*70001678 
  144. 1*77811678 
  145. 1#77800078 
  146. 1#77837### 
  147. 1*00037### 
  148. 1*34000### 
  149. 1*3451*778 
  150. 37###1#345 
  151. 5 5 
  152. 5 5 
  153. 5 6 
  154. 5 7 
  155. 5 8 
  156. 5 9 
  157. 5 10 
  158.  
  159. */
0 0