Codeforces 715B & 716D Complete The Graph 【最短路】 (Codeforces Round #372 (Div. 2))
B. Complete The Graphtime limit per test4 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard outputZS the Coder has drawn an undirected graph of n vertices numbered from 0 to n - 1 and m edges between them. Each edge of the graph is weighted, each weight is a positive integer.
The next day, ZS the Coder realized that some of the weights were erased! So he wants to reassign positive integer weight to each of the edges which weights were erased, so that the length of the shortest path between vertices s and t in the resulting graph is exactly L. Can you help him?
InputThe first line contains five integers n, m, L, s, t (2 ≤ n ≤ 1000, 1 ≤ m ≤ 10 000, 1 ≤ L ≤ 109, 0 ≤ s, t ≤ n - 1, s ≠ t) — the number of vertices, number of edges, the desired length of shortest path, starting vertex and ending vertex respectively.
Then, m lines describing the edges of the graph follow. i-th of them contains three integers, ui, vi, wi(0 ≤ ui, vi ≤ n - 1, ui ≠ vi, 0 ≤ wi ≤ 109). ui and vi denote the endpoints of the edge and wi denotes its weight. If wi is equal to 0then the weight of the corresponding edge was erased.
It is guaranteed that there is at most one edge between any pair of vertices.
OutputPrint "NO" (without quotes) in the only line if it's not possible to assign the weights in a required way.
Otherwise, print "YES" in the first line. Next m lines should contain the edges of the resulting graph, with weights assigned to edges which weights were erased. i-th of them should contain three integers ui, vi and wi, denoting an edge between vertices ui and vi of weight wi. The edges of the new graph must coincide with the ones in the graph from the input. The weights that were not erased must remain unchanged whereas the new weights can be any positive integer not exceeding 1018.
The order of the edges in the output doesn't matter. The length of the shortest path between s and t must be equal to L.
If there are multiple solutions, print any of them.
Examplesinput5 5 13 0 4
0 1 5
2 1 2
3 2 3
1 4 0
4 3 4outputYES
0 1 5
2 1 2
3 2 3
1 4 8
4 3 4input2 1 123456789 0 1
0 1 0outputYES
0 1 123456789input2 1 999999999 1 0
0 1 1000000000outputNONoteHere's how the graph in the first sample case looks like :
In the first sample case, there is only one missing edge weight. Placing the weight of 8 gives a shortest path from 0 to 4 of length 13.
In the second sample case, there is only a single edge. Clearly, the only way is to replace the missing weight with 123456789.
In the last sample case, there is no weights to assign but the length of the shortest path doesn't match the required value, so the answer is "NO".
题目链接:
http://codeforces.com/contest/715/problem/B
http://codeforces.com/contest/716/problem/D
题目大意:
N个点M条无向边(N<=1000,M<=10000),一个值L,起点S,终点T,M条连接u,v的边,只有边权z为0的要修改为任意不超过1018的正数。
求是否有一种修改方案使得从S到T的最短路恰为L。有则输出YES和每条边修改后的值,没有输出NO。
题目思路:
【最短路】
先从T开始跑最短路,边为0的视为断路。求出每个点x不经过边权为0的边到T的最短路dd[x]。如果dd[S]<L则无解。
接下来从S开始跑最短路,对于当前的now->to,如果当前边权z为0,则修改为L-d[now]-dd[to],如果小于1则必须为1,将新的边权z赋值给原来的边喝它的反向边。
如果d[T]>L则无解。否则即为有解。
(思路是队友告诉我的,这个过程实际是枚举在哪一条边之后没有走0的边,用dijkstra写,每次取出d最小的还未取出的点,开始往下走,我SPFA WA了无数次)
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<stack> 10 #include<queue> 11 #include<set> 12 #include<bitset> 13 #include<memory.h> 14 #include<time.h> 15 #include<stdio.h> 16 #include<stdlib.h> 17 #include<string.h> 18 //#include<stdbool.h> 19 #include<math.h> 20 #define min(a,b) ((a)<(b)?(a):(b)) 21 #define max(a,b) ((a)>(b)?(a):(b)) 22 #define abs(a) ((a)>0?(a):(-(a))) 23 #define lowbit(a) (a&(-a)) 24 #define sqr(a) ((a)*(a)) 25 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 26 #define mem(a,b) memset(a,b,sizeof(a)) 27 #define eps (1e-10) 28 #define J 10000 29 #define mod 1000000007 30 #define MAX 0x7f7f7f7f 31 #define PI 3.14159265358979323 32 #pragma comment(linker,"/STACK:1024000000,1024000000") 33 #define N 1004 34 #define M 10004 35 using namespace std; 36 typedef long long LL; 37 double anss; 38 LL aans; 39 int cas,cass; 40 int n,m,lll,ans; 41 int S,T; 42 LL L; 43 int last[N]; 44 LL d[N],dd[N]; 45 bool u[N]; 46 struct xxx 47 { 48 int from,to,next; 49 LL q; 50 }a[M<<1]; 51 bool cmp(int a,int b) 52 { 53 return d[a]>d[b]; 54 } 55 void add(int x,int y,int z) 56 { 57 a[++lll].next=last[x]; 58 a[lll].from=x,a[lll].to=y; 59 a[lll].q=z; 60 last[x]=lll; 61 } 62 void dijkstra(bool f) 63 { 64 int i,j,k,now,to; 65 LL q; 66 mem(u,0);mem(d,14); 67 if(f)d[S]=0; 68 else d[T]=0; 69 for(i=0;i<n;i++) 70 { 71 for(j=0,now=n;j<n;j++)if(!u[j] && d[now]>d[j])now=j; 72 u[now]=1; 73 for(j=last[now];j;j=a[j].next) 74 { 75 to=a[j].to; 76 if(f) 77 { 78 q=a[j].q; 79 if(!q)q=max(L-d[now]-dd[to],1); 80 a[j].q=a[j^1].q=q; 81 d[to]=min(d[to],d[now]+a[j].q); 82 } 83 else if(a[j].q) 84 d[to]=min(d[to],d[now]+a[j].q); 85 } 86 } 87 } 88 int main() 89 { 90 #ifndef ONLINE_JUDGEW 91 // freopen("1.txt","r",stdin); 92 // freopen("2.txt","w",stdout); 93 #endif 94 int i,j,k; 95 int x,y,z; 96 // init(); 97 // for(scanf("%d",&cass);cass;cass--) 98 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 99 // while(~scanf("%s",s)) 100 while(~scanf("%d",&n)) 101 { 102 scanf("%d%I64d%d%d",&m,&L,&S,&T); 103 lll=1;mem(last,0); 104 for(i=1;i<=m;i++) 105 { 106 scanf("%d%d%d",&x,&y,&z); 107 add(x,y,z),add(y,x,z); 108 } 109 dijkstra(0); 110 if(d[S]<L){puts("NO");continue;} 111 memcpy(dd,d,sizeof(dd)); 112 dijkstra(1); 113 if(d[T]>L){puts("NO");continue;} 114 puts("YES"); 115 for(i=2;i<=m+m;i+=2) 116 printf("%d %d %I64d\n",a[i].from,a[i].to,a[i].q); 117 } 118 return 0; 119 } 120 /* 121 // 122 123 // 124 */