POJ P3268 Silver Cow Party

题目链接:http://poj.org/problem?id=3268

题目大意就是在一张有向图中求解任意点到点x的来回的最小路径的最大值。

对于有向图:

用原图+Dijkstra可以得到点x到其他点的最短路径。

将图转置+Dijkstra可以得到其他点到点x的最短路径。

将两张图的最短路径相加即可得到点x到其他点来回的最短路径,再遍历最大值即可。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<string>
  4 #include<map>
  5 #include<set>
  6 #include<queue>
  7 #include<stack>
  8 #include<cmath>
  9 #include<ctime> 
 10 #include<algorithm>
 11 #include<cstring>
 12 #define  sc scanf
 13 #define  pr printf
 14 #define MAXN 1010
 15 #define INF 0x7fffffff
 16 #define endd puts("");
 17 #define int long long
 18 #define il inline
 19 #define PI  3.1415926535898
 20 #define INF_MIN -214783647
 21 using namespace std;
 22 il int read() {
 23     int s = 0, f = 1;
 24     char ch = getchar();
 25     while (ch<'0' || ch>'9') {
 26         if (ch == '-')
 27             f = -1;
 28         ch = getchar();
 29     }
 30     while (ch >= '0'&&ch <= '9') {
 31         s = s * 10 + ch - '0';
 32         ch = getchar();
 33     }
 34     return s * f;
 35 }
 36 /*--------------------head---------------------------*/
 37 struct edge{
 38     int dis,to,head;
 39 }e[MAXN*MAXN],re[MAXN*MAXN];
 40 
 41 int cnt,n,m,x,rcnt;
 42 
 43 int vis[MAXN],head[MAXN],rhead[MAXN],dis[MAXN],ans[MAXN];
 44 
 45 inline void add_edge(int u,int v,int d,int r){
 46     if(r==1){
 47         e[++cnt].dis=d;
 48         e[cnt].to=v;
 49         e[cnt].head=head[u];
 50         head[u]=cnt;
 51     }
 52     else{
 53         re[++rcnt].dis=d;
 54         re[rcnt].to=v;
 55         re[rcnt].head=rhead[u];
 56         rhead[u]=rcnt;
 57     }
 58 }
 59 
 60 inline void dij(edge E[],int Head[]){
 61     priority_queue<pair<int,int> > q;
 62     memset(vis,0,sizeof(vis));
 63     for(int i=0;i<=n;i++) dis[i]=INF;
 64     while(!q.empty()) q.pop();
 65     
 66     dis[x]=0;  
 67     q.push(make_pair(0,x));
 68     while(!q.empty()){
 69         int u=q.top().second;
 70         q.pop();
 71         if(vis[u])  continue;
 72         vis[u]=1;
 73         for(int i=Head[u];i;i=E[i].head){
 74             int y=E[i].to;
 75             if(dis[y]>dis[u]+E[i].dis){
 76                 dis[y]=dis[u]+E[i].dis;
 77                 if(!vis[y])
 78                     q.push(make_pair(-dis[y],y));
 79             }
 80         }
 81     }
 82     
 83 }
 84 
 85 signed main()
 86 {
 87     int SUM=-1;
 88     n=read();  m=read();  x=read();
 89     for(int i=0;i<m;i++){
 90         int u,v,d;
 91         u=read();  v=read();  d=read();
 92         add_edge(u,v,d,1);
 93         add_edge(v,u,d,0);
 94     }
 95     dij(e,head);
 96     for(int i=1;i<=n;i++)
 97         if(dis[i]!=INF) 
 98             ans[i]+=dis[i];
 99     //for(int i=1;i<=n;i++) cout<<ans[i]<<' ';
100     //endd
101     dij(re,rhead);
102     for(int i=1;i<=n;i++){
103         if(dis[i]!=INF)
104             ans[i]+=dis[i];
105         SUM=max(SUM,ans[i]);
106     }
107     //for(int i=1;i<=n;i++) cout<<ans[i]<<' ';
108     //endd
109     cout<<SUM;
110     return 0;
111 }

 

posted @ 2020-12-03 21:55  面向题目编程  阅读(122)  评论(0)    收藏  举报