洛谷P1396 营救
多种解法:
1.spfa,只是松弛操作时更新的是路径上最大值的最小值;(最慢。。24ms)
#include<bits/stdc++.h> #define inf 0x7fffffff using namespace std; struct node { int n,v; node *next; }*e[20001]; int n,m,s,t; void Cin(int &x) { char c=getchar();x=0; while(c>'9'||c<'0')c=getchar(); while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar(); } int d[10001]; queue<int>q; int main() { Cin(n),Cin(m),Cin(s),Cin(t); node *p; node *Q; int x; for(int i=1;i<=m;i++) { p=new node(); Q=new node(); Cin(x),Cin(p->n),Cin(p->v); Q->n=x; Q->v=p->v; if(e[p->n]==NULL) { e[p->n]=Q; } else { Q->next=e[p->n]->next; e[p->n]->next=Q; } if(e[x]==NULL) { e[x]=p; } else { p->next=e[x]->next; e[x]->next=p; } } for(int i=1;i<=n;i++) d[i]=inf; d[s]=0; q.push(s); while(!q.empty()) { p=e[q.front()]; while(p!=NULL) { if(max(d[q.front()],p->v)<d[p->n]) { d[p->n]=max(d[q.front()],p->v); q.push(p->n); } p=p->next; } q.pop(); } cout<<d[t]; return 0; }
2.Kruskal 从小到大加边,直到getfather(s)==getfather(t),然后输出当前边权;(最快。。4ms)
#include<bits/stdc++.h> using namespace std; struct kruskal { int l,r,t; bool operator<(const kruskal&a)const { return t<a.t; } }e[20001]; int dad[10001]; int n,m; void Cin(int &x) { char c=getchar();x=0; while(c>'9'||c<'0')c=getchar(); while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar(); } int getfather(int x) { if(dad[x]==x) return x; dad[x]=getfather(dad[x]); return dad[x]; } int s,T; int main() { Cin(n),Cin(m),Cin(s),Cin(T); for(int i=1;i<=m;i++) { Cin(e[i].l),Cin(e[i].r),Cin(e[i].t); } sort(e+1,e+m+1); for(int i=1;i<=n;i++) dad[i]=i; int cnt=0; int tt=0; for(int i=1;i<=m;i++) { if(getfather(e[i].l)!=getfather(e[i].r)) { dad[getfather(e[i].l)]=e[i].r; if(getfather(s)==getfather(T)) { cout<<e[i].t; return 0; } } } return 0; }
3.Bfs+二分答案,二分出来mid,然后用边权小于mid的跑bfs,直到找到ti,然后r=mid,
否则l=mid+1;
#include<bits/stdc++.h> using namespace std; struct node { int n,v; node *next; }*e[20001]; bool wnt[10001]; int n,m; void Cin(int &x) { char c=getchar();x=0; while(c>'9'||c<'0')c=getchar(); while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar(); } int s,t; int Max; queue<int>q; bool bfs(int mid) { q.push(s); wnt[s]=true; node *p; while(!q.empty()) { p=e[q.front()]; while(p!=NULL) { if(p->v<=mid&&wnt[p->n]==false) { if(p->n==t) { return true; } else { q.push(p->n); wnt[p->n]=true; } } p=p->next; } q.pop(); } return false; } int main() { Cin(n),Cin(m),Cin(s),Cin(t); node *p; node *P; int x; for(int i=1;i<=m;i++) { p=new node(); P=new node(); Cin(x),Cin(p->n),Cin(p->v); Max=max(Max,p->v); P->v=p->v; P->n=x; if(e[x]==NULL) { e[x]=p; } else { p->next=e[x]->next; e[x]->next=p; } if(e[p->n]==NULL) { e[p->n]=P; } else { P->next=e[p->n]->next; e[p->n]->next=P; } } int l=0,r=Max,mid; while(l<r) { mid=(l+r)/2; if(bfs(mid)) { r=mid; while(!q.empty()) q.pop(); memset(wnt,false,sizeof(wnt)); } else { l=mid+1; while(!q.empty()) q.pop(); memset(wnt,false,sizeof(wnt)); } } cout<<l; return 0; }