『USACO』安全路經Travel (bzoj 1576)
阿新 • • 發佈:2018-09-26
路徑 using 原來 int main tmp cmp set info
題目鏈接
題目描述
解題思路
沒啥思路。
首先能想到要做一遍SPFA(堆優化),順便記錄一下每個點的最短路是由哪個邊來的。
顯然,1到所有的點的最短路組成了一棵樹,但是接下來就不知道咋做了2333333。
我們發現:因為不能從原來的路徑過來,所以我們要選擇另一條路,也就將終點和另外的一個節點連接達到最短路,我們仔細想想,我們構造的最短路樹已經滿足了每個點到1號點的距離最近,所以從別的點轉移過來一定能得到最近的距離。
先睡覺,明天再寫qwq??
代碼
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<queue> using namespace std; const int maxn=100050; const int maxm=200050; int n,m,cnt=0,tot=0; int head[maxm<<1],ne[maxm<<1],to[maxm<<1],v[maxm<<1],a[maxm],b[maxm],c[maxm]; bool flag[maxm<<1]; int dis[maxn],from[maxn],fa[maxn],num[maxn],ans[maxn]; bool vis[maxn]; struct nod{ int x; }; struct edge{ int f,t,val; }; edge e[maxm<<1]; inline bool operator < (nod a,nod b){ return dis[a.x]>dis[b.x]; } inline void add(int f,int t,int val){ ne[++cnt]=head[f],head[f]=cnt,to[cnt]=t,v[cnt]=val; } inline void ini(){ memset(ans,-1,sizeof(ans)); for(register int i=0;i<maxn;i++)fa[i]=i; } inline int getfa(int x){ return fa[x]==x?x:fa[x]=getfa(fa[x]); } inline bool cmp(edge a,edge b){ return a.val<b.val; } inline void spfa(){ priority_queue<nod>q; memset(dis,0x3f,sizeof(dis)); vis[1]=1,dis[1]=0; q.push((nod){1}); while(!q.empty()){ nod x=q.top(); q.pop(); vis[x.x]=0; for(register int i=head[x.x];i;i=ne[i]){ if(dis[to[i]]>dis[x.x]+v[i]){ dis[to[i]]=dis[x.x]+v[i]; from[to[i]]=x.x; num[to[i]]=i; if(!vis[to[i]]){ vis[to[i]]=1; q.push((nod){to[i]}); } } } } } int main(){ ini(); scanf("%d%d",&n,&m); for(register int i=1;i<=m;i++){ scanf("%d%d%d",&a[i],&b[i],&c[i]); add(a[i],b[i],c[i]),add(b[i],a[i],c[i]); } spfa(); for(register int i=2;i<=n;i++){ int tmp=num[i]; if(num[i]&1)tmp++; else tmp--; flag[num[i]]=flag[tmp]=1; } for(register int i=1;i<=m;i++){ if(flag[i<<1])continue; e[++tot]=(edge){a[i],b[i],dis[a[i]]+dis[b[i]]+c[i]}; } sort(e+1,e+tot+1,cmp); for(register int i=1;i<=tot;i++){ int f=e[i].f,t=e[i].t; f=getfa(f),t=getfa(t); while(f!=t){ if(dis[f]<dis[t])swap(f,t); ans[f]=e[i].val-dis[f]; fa[f]=from[f]; f=getfa(f); } } for(register int i=2;i<=n;i++){ printf("%d\n",ans[i]); } }
『USACO』安全路經Travel (bzoj 1576)