• 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
  • 相关阅读:
    PHP链接xmpp,openfire新增用户,聊天室
    mysql数据库导入导出 授权
    docker容器的跨主机连接
    php编译安装
    WebIM web即时通信 基于openfire+smack的Android、Web、PC开发(一)
    某电商平台开发记要——客服系统
    架构
    kafka-python如何关闭debug日志
    【python编码】 UnicodeDecodeError 分析和解决
    I、Identical Day from 第二届“联想杯”
  • 原文地址:https://www.cnblogs.com/0803yijia/p/3243233.html
Copyright © 2020-2023  润新知