洛谷 P1396 營救
阿新 • • 發佈:2017-08-19
org d+ ctype class empty ios 輸入輸出 生成 -m
題目描述
“咚咚咚……”“查水表!”原來是查水表來了,現在哪裏找這麽熱心上門的查表員啊!小明感動的熱淚盈眶,開起了門……
媽媽下班回家,街坊鄰居說小明被一群陌生人強行押上了警車!媽媽豐富的經驗告訴她小明被帶到了t區,而自己在s區。
該市有m條大道連接n個區,一條大道將兩個區相連接,每個大道有一個擁擠度。小明的媽媽雖然很著急,但是不願意擁擠的人潮沖亂了她優雅的步伐。所以請你幫她規劃一條從s至t的路線,使得經過道路的擁擠度最大值最小。
輸入輸出格式
輸入格式:
第一行四個數字n,m,s,t。
接下來m行,每行三個數字,分別表示兩個區和擁擠度。
(有可能兩個區之間有多條大道相連。)
輸出格式:
輸出題目要求的擁擠度。
輸入輸出樣例
輸入樣例#1:3 3 1 3 1 2 2 2 3 1 1 3 3輸出樣例#1:
2
說明
數據範圍
30% n<=10
60% n<=100
100% n<=10000,m<=2n,擁擠度<=10000
題目保證1<=s,t<=n且s<>t,保證可以從s區出發到t區。
樣例解釋:
小明的媽媽要從1號點去3號點,最優路線為1->2->3。
1.二分擁擠度+spfa驗證
屠龍寶刀點擊就送
#include <ctype.h> #include <cstring> #include <cstdio> #include <queue> #define N 20005 using namespace std; inline void read(int &x) { register char ch=getchar(); for(x=0;!isdigit(ch);ch=getchar()); for(;isdigit(ch);ch=getchar()) x=x*10+ch-‘0‘; } struct Edge { int to,val; Edge * next; }edge[N<<1],*head[N]; bool vis[N]; int sumedge,cnt[N],n,m,s,t,dis[N]; inline void ins(int u,int v,int w) { edge[++sumedge].next=head[u]; edge[sumedge].to=v; edge[sumedge].val=w; head[u]=edge+sumedge; } bool check(int Limit) { queue<int>q; q.push(s); for(int i=1;i<=n;i++) vis[i]=0,cnt[i]=0,dis[i]=0x3f3f3f3f; dis[s]=0; cnt[s]=1; vis[s]=1; for(int now=q.front();!q.empty();q.pop(),now=q.front()) { vis[now]=0; if(cnt[now]>=n) return 0; for(Edge * u=head[now];u;u=u->next) { int v=u->to; if(u->val<=Limit&&dis[v]>dis[now]+u->val) { dis[v]=dis[now]+u->val; if(!vis[v]) { vis[v]=1; q.push(v); cnt[v]++; } } } } return dis[t]!=0x3f3f3f3f; } int main() { read(n);read(m);read(s);read(t); for(int x,y,z;m--;) { read(x);read(y);read(z); ins(x,y,z); ins(y,x,z); } int ans; for(int l=0,r=0x3f3f3f3f,mid;l<=r;) { mid=l+r>>1; if(check(mid)) r=mid-1,ans=mid; else l=mid+1; } printf("%d\n",ans); return 0; }
2 spfa
#include <ctype.h> #include <cstring> #include <cstdio> #include <queue> #define N 20005 using namespace std; inline void read(int &x) { register char ch=getchar(); for(x=0;!isdigit(ch);ch=getchar()); for(;isdigit(ch);ch=getchar()) x=x*10+ch-‘0‘; } struct Edge { int to,val; Edge * next; }edge[N<<1],*head[N]; bool vis[N]; int sumedge,cnt[N],n,m,s,t,dis[N]; inline void ins(int u,int v,int w) { edge[++sumedge].next=head[u]; edge[sumedge].to=v; edge[sumedge].val=w; head[u]=edge+sumedge; } void spfa() { queue<int>q; q.push(s); for(int i=1;i<=n;i++) vis[i]=0,dis[i]=0x3f3f3f3f; dis[s]=0; vis[s]=1; for(int now=q.front();!q.empty();q.pop(),now=q.front()) { vis[now]=0; for(Edge * u=head[now];u;u=u->next) { int v=u->to; if(dis[v]>max(u->val,dis[now])) { dis[v]=max(u->val,dis[now]); if(!vis[v]) { vis[v]=1; q.push(v); } } } } } int main() { read(n);read(m);read(s);read(t); for(int x,y,z;m--;) { read(x);read(y);read(z); ins(x,y,z); ins(y,x,z); } spfa(); printf("%d\n",dis[t]); return 0; }
3 最小生成樹 代碼來自zsq
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 100100 using namespace std; int x,y,z,n,m,s,t,ans,fa[N]; struct Edge { int x,y,z; }edge[N]; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();} return x*f; } int cmp(Edge a,Edge b) { return a.z<b.z; } int find(int x) { if(x==fa[x]) return x; fa[x]=find(fa[x]); return fa[x]; } int main() { n=read(),m=read(),s=read(),t=read(); for(int i=1;i<=m;i++) { x=read(),y=read(),z=read(); edge[i].x=x; edge[i].y=y; edge[i].z=z; } for(int i=1;i<=n;i++) fa[i]=i; sort(edge+1,edge+1+m,cmp); for(int num=0,i=1;i<=m;i++) { x=edge[i].x,y=edge[i].y; int fx=find(x),fy=find(y); if(fx==fy) continue; fa[fx]=fy; num++; ans=max(ans,edge[i].z); if(num==n-1||find(s)==find(t)) break; } printf("%d",ans); return 0; }
洛谷 P1396 營救