HDU 4725 建图

http://acm.hdu.edu.cn/showproblem.php?pid=4725

The Shortest Path in Nya Graph

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7869    Accepted Submission(s): 1766


Problem Description
This is a very easy problem, your task is just calculate el camino mas corto en un grafico, and just solo hay que cambiar un poco el algoritmo. If you do not understand a word of this paragraph, just move on.
The Nya graph is an undirected graph with "layers". Each node in the graph belongs to a layer, there are N nodes in total.
You can move from any node in layer x to any node in layer x + 1, with cost C, since the roads are bi-directional, moving from layer x + 1 to layer x is also allowed with the same cost.
Besides, there are M extra edges, each connecting a pair of node u and v, with cost w.
Help us calculate the shortest path from node 1 to node N.
 

 

Input
The first line has a number T (T <= 20) , indicating the number of test cases.
For each test case, first line has three numbers N, M (0 <= N, M <= 105) and C(1 <= C <= 103), which is the number of nodes, the number of extra edges and cost of moving between adjacent layers.
The second line has N numbers li (1 <= li <= N), which is the layer of ith node belong to.
Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 104), which means there is an extra edge, connecting a pair of node u and v, with cost w.
 

 

Output
For test case X, output "Case #X: " first, then output the minimum cost moving from node 1 to node N.
If there are no solutions, output -1.
 

 

Sample Input
2 3 3 3 1 3 2 1 2 1 2 3 1 1 3 3 3 3 3 1 3 2 1 2 2 2 3 2 1 3 4
 

 

Sample Output
Case #1: 2 Case #2: 3
 

 

Source
一开始无脑暴力建 N1*N2的图,后来超时后才发现,如果层数稀疏,点数密集的话建的边数上亿,肯定要超时的,我们想办法巧妙地建图。
把每一层看做是一个点,通过点->层->点的连接从而实现层与层的连接,可以少建许多边,但我第一次没考虑周到,让点与对应的层建立了双向边,这是致命的,,
因为每一层的点之间距离并非是0,这样构图的话每一层得点相互之间都能0距离显然是错误的。
考虑建单向边,让每一层向层上的点建一条0边,然后对于每个点,向与其相邻且存在的层建立一条权值为C的边,这样就符合了题意。
spfa和dij都写了感觉复杂度差不多,但是第一次建图错误时spfa提示TLE,dij返回WA不知道是否说明dij快点- -反正二者AC的时间差不大多
  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<queue>
  5 using namespace std;
  6 #define inf 0x3f3f3f3f
  7 inline int read()
  8 {
  9     int r=0;  char c=getchar();
 10     while(!isdigit(c)) c=getchar();
 11     while(isdigit(c)) {r=r*10+c-'0';c=getchar();}
 12     return r;
 13 }
 14 struct Edge
 15 {
 16     int to,w,next;
 17 }e[600005];
 18 int cnt,first[200005];
 19 void add(int u,int v,int w)
 20 {
 21     e[cnt].to=v;
 22     e[cnt].w=w;
 23     e[cnt].next=first[u];
 24     first[u]=cnt++;
 25 }
 26 struct node
 27 {
 28     int u,w;
 29     bool operator<(const node &x)const{
 30     return w>x.w;
 31     }
 32 };
 33 int d[200005];
 34 int dij(int N)
 35 {
 36     bool vis[200005];
 37     priority_queue<node>Q;
 38     memset(vis,0,sizeof(vis));
 39     memset(d,inf,sizeof(d));
 40     d[1]=0;
 41     Q.push(node{1,0});
 42     while(!Q.empty()){
 43         node t1=Q.top();Q.pop();
 44         int u=t1.u;
 45         if(vis[u]) continue;
 46         vis[u]=1;
 47         if(u==N) break;
 48         for(int i=first[u];i+1;i=e[i].next){
 49             Edge x=e[i];
 50             if(!vis[x.to]&&d[x.to]>d[u]+x.w){
 51                 d[x.to]=d[u]+x.w;
 52                 Q.push(node{x.to,d[x.to]});
 53             }
 54         }
 55     }
 56     return d[N]==inf?-1:d[N];
 57 }
 58 int spfa(int N)
 59 {
 60     bool vis[200005];
 61     queue<int>Q;
 62     memset(vis,0,sizeof(vis));
 63     memset(d,inf,sizeof(d));
 64     Q.push(1);
 65     vis[1]=1;
 66     d[1]=0;
 67     while(!Q.empty()){
 68         int u=Q.front(); Q.pop();
 69         vis[u]=0;
 70         for(int i=first[u];i+1;i=e[i].next){
 71             Edge x=e[i];
 72             if(d[x.to]>d[u]+x.w){
 73                 d[x.to]=d[u]+x.w;
 74                 if(!vis[x.to]){
 75                     Q.push(x.to);
 76                 }
 77             }
 78         }
 79     }
 80     return d[N]==inf?-1:d[N];
 81 }
 82 int main()
 83 {
 84     //ios::sync_with_stdio(false);
 85     int T,N,M,C,i,j,k=0;
 86     int u,v,w,x[100005];
 87     bool layer[100005];
 88    #ifndef ONLINE_JUDGE
 89    freopen("in.txt","r",stdin);
 90    #endif
 91     T=read();
 92     for(int cas=1;cas<=T;++cas)
 93     {
 94         cnt=0;
 95         memset(first,-1,sizeof(first));
 96         memset(layer,0,sizeof(layer));
 97         cin>>N>>M>>C;
 98         for(i=1;i<=N;++i)
 99         {
100             x[i]=read();
101             layer[x[i]]=1;
102         }
103        for(i=1;i<=N;++i)
104         {
105             add(x[i]+N,i,0);
106             add(i,x[i]+N,0);
107             if(x[i]>1&&layer[x[i]-1])
108                 add(i,x[i]+N-1,C);
109             if(x[i]<N&&layer[x[i]+1])
110                 add(i,x[i]+N+1,C);
111         }
112         while(M--){
113         scanf("%d%d%d",&u,&v,&w);
114             add(u,v,w);
115             add(v,u,w);
116         }
117         printf("Case #%d: %d\n",cas,dij(N)/*spfa(N)*/);
118     }
119     return 0;
120 }

 

posted @ 2017-08-14 22:09  *zzq  阅读(171)  评论(0编辑  收藏  举报