Poj 3592 Instantaneous Transference

  1. 先缩点,把环都缩在一起,之后sfpa求最长路


  2. #include <queue>  
  3. #include <cstdio>  
  4. #include <cstring>  
  5. #include <iostream>  
  6. #include <algorithm>  
  7. #define MAX 20010  
  8. using namespace std;  
  9.   
  10. int cases;  
  11. int m,n;  
  12. char src[50][50];  
  13. int transmit[MAX],points;  
  14.   
  15. int head[MAX],total;  
  16. int next[MAX],aim[MAX];  
  17.   
  18. int dfn[MAX],low[MAX],_clock;  
  19. int stack[MAX],top;  
  20. bool in_stack[MAX];  
  21. int changed[MAX],scc,val[MAX];  
  22. int a[MAX];  
  23.   
  24. int _head[MAX],_total;  
  25. int _next[MAX],_aim[MAX];  
  26.   
  27. int f[MAX];  
  28. bool v[MAX];  
  29.   
  30. inline void Initialize()  
  31. {  
  32.     total = _total = _clock = top = points = scc = 0;  
  33.     memset(head,0,sizeof(head));  
  34.     memset(_head,0,sizeof(_head));  
  35.     memset(dfn,0,sizeof(dfn));  
  36.     memset(in_stack,false,sizeof(in_stack));  
  37.     memset(val,0,sizeof(val));  
  38. }  
  39.   
  40. inline void Add(int x,int y)  
  41. {  
  42.     next[++total] = head[x];  
  43.     aim[total] = y;  
  44.     head[x] = total;  
  45. }  
  46.   
  47. inline void _Add(int x,int y)  
  48. {  
  49.     _next[++_total] = _head[x];  
  50.     _aim[_total] = y;  
  51.     _head[x] = _total;  
  52. }  
  53.   
  54. void Tarjan(int x)  
  55. {  
  56.     dfn[x] = low[x] = ++_clock;  
  57.     in_stack[x] = true;  
  58.     stack[++top] = x;  
  59.     for(int i = head[x]; i; i = next[i]) {  
  60.         if(!dfn[aim[i]])  
  61.             Tarjan(aim[i]),low[x] = min(low[x],low[aim[i]]);  
  62.         else if(in_stack[aim[i]])  
  63.             low[x] = min(low[x],dfn[aim[i]]);  
  64.     }  
  65.     if(dfn[x] == low[x]) {  
  66.         scc++;  
  67.         int temp;  
  68.         do {  
  69.             temp = stack[top--];  
  70.             changed[temp] = scc;  
  71.             in_stack[temp] = false;  
  72.             val[scc] += a[temp];  
  73.         }while(temp != x);  
  74.     }  
  75. }  
  76.   
  77. inline void SPFA()  
  78. {  
  79.     static queue<int> q;  
  80.     while(!q.empty())   q.pop();  
  81.     memset(f,0,sizeof(f));  
  82.     memset(v,false,sizeof(v));  
  83.     f[changed[0]] = val[changed[0]];  
  84.     q.push(changed[0]);  
  85.     while(!q.empty()) {  
  86.         int x = q.front(); q.pop();  
  87.         v[x] = false;  
  88.         for(int i = _head[x]; i; i = _next[i])  
  89.             if(f[_aim[i]] < f[x] + val[_aim[i]]) {  
  90.                 f[_aim[i]] = f[x] + val[_aim[i]];  
  91.                 if(!v[_aim[i]]) {  
  92.                     v[_aim[i]] = true;  
  93.                     q.push(_aim[i]);  
  94.                 }  
  95.             }  
  96.     }  
  97. }  
  98.   
  99. int main()  
  100. {  
  101.     for(cin >> cases; cases; --cases) {  
  102.         scanf("%d%d",&n,&m);  
  103.         Initialize();  
  104.         for(int i = 0; i < n; ++i)  
  105.             scanf("%s",src[i]);  
  106.         for(int i = 0; i < n; ++i)  
  107.             for(int x,y,j = 0;j < m; ++j)  
  108.                 if(src[i][j] == '*') {  
  109.                     scanf("%d%d",&x,&y);  
  110.                     a[i * m + j] = 0;  
  111.                     if(src[x][y] != '#')  
  112.                         Add(i * m + j,x * m + y);  
  113.                     if(i + 1 < n && src[i + 1][j] != '#')  
  114.                         Add(i * m + j,(i + 1) * m + j);  
  115.                     if(j + 1 < m && src[i][j + 1] != '#')  
  116.                         Add(i * m + j,i * m + j + 1);  
  117.                 }  
  118.                 else if(src[i][j] != '#') {  
  119.                     a[i * m + j] = src[i][j] - '0';  
  120.                     if(i + 1 < n && src[i + 1][j] != '#')  
  121.                         Add(i * m + j,(i + 1) * m + j);  
  122.                     if(j + 1 < m && src[i][j + 1] != '#')  
  123.                         Add(i * m + j,i * m + j + 1);  
  124.                 }  
  125.         for(int i = 0; i < m * n; ++i)  
  126.             if(!dfn[i]) Tarjan(i);  
  127.         for(int x = 0; x < m * n; ++x)  
  128.             for(int i = head[x]; i; i = next[i])  
  129.                 if(changed[x] != changed[aim[i]])  
  130.                     _Add(changed[x],changed[aim[i]]);  
  131.         SPFA();  
  132.         int *ans = max_element(f + 1,f + scc + 1);  
  133.         printf("%d\n",*ans);  
  134.     }  
  135.     return 0;  

  1. }


不用spfa用dfs也可以
int dfs( int u) //搜索最大值
{  
if (!vis[u])
{  
vis[u]= 1 ;  
int ans= 0 ;  
for ( int i=Head2[u];i!=- 1 ;i=Li[i].next)  
{  
ans = max(ans,dfs(Li[i].v)); 
}  
a[u]+=ans;  
}  
return a[u];
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值