【Codeforces】716D Complete The Graph
D. Complete The Graph
Solution
特判掉原本最短路(没有加入0边)<l→"NO"
分析一下,s→t的最短路,贪心,加入0边,先不管取值,先一条条赋为1(最小positive integer),如果当前最短路<l是不是说明当前这条边是最短路的一部分,所以答案就出来了,将这条边赋值为l-d[t]+1,如果最短路仍>l,而这已经是这条边的最优贡献,所以赋值为1继续做.
然后注意一下细节即可(WA了4发~~)
复杂度:O(nmlogn)(优化:对了,每次做最短路,当前值已经>l可以直接退出,所以其实跑得很快296MS)
// This file is made by YJinpeng,created by XuYike's black technology automatically. // Copyright (C) 2016 ChangJun High School, Inc. // I don't know what this program is. #include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #include <queue> #define IN inline #define RG register #define MOD 1000000007 #define INF 1e9+1 using namespace std; typedef long long LL; const int MAXN=1010; const int MAXM=20010; inline int gi() { register int w=0,q=0;register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')q=1,ch=getchar(); while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar(); return q?-w:w; } int tot,cnt,S[MAXM],T[MAXM]; struct Dijskra{ static const int N=1010,M=(N*10)<<1; int n,t,l;int d[N],fr[N];int to[M],ne[M],be[M],W[M];bool u[N]; struct node{ int s,p; bool operator<(node a)const{return s>a.s;} }; priority_queue<node>q; IN void link(RG int u,RG int v,RG int w){ //if(w>l)return; this some edges didn't get to[++t]=v;ne[t]=fr[u];fr[u]=t;W[t]=w;be[t]=u; } int Dij(int begin,int end){ for(int i=0;i<n;i++)d[i]=INF; q.push((node){d[begin]=0,begin});memset(u,0,sizeof(u)); while(!q.empty()){ while(u[q.top().p]&&!q.empty())q.pop(); if(q.empty())break; int x=q.top().p;q.pop();u[x]=1; if(x==end||d[x]>l)break; for(int o=fr[x],y;y=to[o],o;o=ne[o]) if(d[x]+W[o]<d[y]&&d[x]+W[o]<=l){ d[y]=d[x]+W[o]; q.push((node){d[y],y}); } } return d[end]; } void pri(int end){ printf("YES\n"); for(int i=1;i<t-1;i+=2) printf("%d %d %d\n",be[i],to[i],W[i]); printf("%d %d %d\n",be[t-1],to[t-1],l-d[end]+W[t-1]);//this W[t-1] for(int i=tot;i<=cnt;i++)printf("%d %d %d\n",S[i],T[i],(int)INF);exit(0); } }e; int main() { freopen("D.in","r",stdin); freopen("D.out","w",stdout); int n=gi(),m=gi(),l=gi(),s=gi(),t=gi();e.l=l;e.n=n; for(int i=1;i<=m;i++){ int u=gi(),v=gi(),w=gi(); if(w)e.link(u,v,w),e.link(v,u,w); else S[++cnt]=u,T[cnt]=v; }tot=1;//this if(e.Dij(s,t)<l){printf("NO");return 0;} if(e.d[t]==l)e.pri(t); for(;tot<=cnt;tot++){ e.link(S[tot],T[tot],1);e.link(T[tot],S[tot],1); if(e.Dij(s,t)<=l)break; }tot++; if(tot>cnt+1)return 0*puts("NO"); e.pri(t); return 0; }