POJ 1797 Heavy Transportation(最大生成樹)
題目大意:給定n個頂點,以及m條邊的描述,每條邊的描述包括:起點、終點、權重。現在要從頂點1出發到達頂點n,求路徑中能夠承受的最大權重。
解題思路:讀懂題意很重要,樣例比較水,要去深入理解題目,同時注意輸出格式。
1)本題要求出的是從頂點1到頂點n的所有可行路徑中各邊權值的最小值的最大值。即max(min(可行路徑邊))。很顯然是最短路徑的變形。
2)Prim演算法:其實就是找一條帶權路徑,使得路徑上最小的權值最大化,只要求一次最大生成樹即可,沒有什麼複雜的演算法,不過這個題要對最小生成樹有更深的理解
prim演算法:
1、設有一集合S,首先,將起點s(最後就成了最小生成樹的根節點)放入集合,則S = {s}
2、找到距離集合S最近的一點u,加入S集合
3、通過點u,更新其餘未進入集合S的點到集合S的距離
4、如果集合S外沒有點了,結束,否則轉到步驟2
其實整個過程中就是在找到一個距離起點集合S路徑最小的點,加入進來,然後不斷更新,這就像在建一棵連通樹,在保證連通的情況下,不斷的加入新的葉子節點,由於每次入的邊權最小,所以最後建成的就是一棵最小生成樹,它能保證起點到任意一點的路徑上最小的權值最小化;同理,最大生成樹就是在加點的時候找權值最大的加入就行了。
好多方法都能過,主要是題意的理解,SPFA,最短路,等。
最短路演算法:
#include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> #include<stdlib.h> #include<math.h> #include<queue> #include<map> #include<stack> #define mann 1008 #define INF 1000000001 typedef long long LL; using namespace std; int n,m; int vis[mann],dis[mann]; int mp[mann][mann]; void dijstra(int cur) { for(int i=1;i<=n;i++) { dis[i]=mp[cur][i]; vis[i]=0; } dis[cur]=0; vis[cur]=1; int minn,pos,ans=INF; for(int i=1;i<n;i++) { minn=-2; for(int j=1;j<=n;j++) { if(!vis[j]&&dis[j]>minn) { minn=dis[j]; pos=j; } } vis[pos]=1; for(int j=1;j<=n;j++) { if(!vis[j]&&dis[j]<min(mp[pos][j],dis[pos])) dis[j]=min(mp[pos][j],dis[pos]); } } } int main() { int t,T=0; scanf("%d",&t); while(t--) { int u,v,w; memset(dis,0,sizeof(dis)); memset(mp,0,sizeof(mp));//注意資料的初始化 scanf("%d%d",&n,&m); for(int i=0; i<m; i++) { scanf("%d%d%d",&u,&v,&w); mp[u][v]=mp[v][u]=w; } dijstra(1); printf("Scenario #%d:\n%d\n\n",++T,dis[n]); } }
prim演算法:
#include<stdio.h> #include<algorithm> #include<iostream> #include<string.h> using namespace std; #define mann 1005 #define INF 0x3f3f3f3f int aa[mann],mp[mann][mann]; int vis[mann],low[mann]; int n,m; int prim() { memset(vis,0,sizeof(vis)); int pos=1,sum=0,minn; vis[pos]=1; low[pos]=0; for(int i=1;i<=n;i++) { if(i!=pos) low[i]=mp[pos][i]; } for(int i=0;i<n;i++) { minn=-INF; for(int j=1;j<=n;j++) { if(!vis[j]&&low[j]>minn) { minn=low[j]; pos=j; } } sum=min(minn,sum); if(pos==n) break;//並不一定要走完所有的點,走到終點就行 vis[pos]=1; //printf("%d*%d\n",pos,minn); for(int j=1;j<=n;j++) { if(!vis[j]&&low[j]<mp[pos][j]) low[j]=mp[pos][j]; } } return sum; } int main() { int t,T=0 ; scanf("%d",&t); while(t--) { memset(mp,-INF,sizeof(mp)); int a,b,c; scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); mp[a][b]=mp[b][a]=c; } printf("Scenario #%d:\n%d\n\n",++T,prim()); } }
Kruskal:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<queue>
typedef long long LL;
using namespace std;
#define INF 0x3f3f3f3f
const int maxn=1000005;
int set[maxn];
int n,m;
struct node
{
int u,v,w;
} c[maxn];
bool cmp(node aa,node bb)
{
return aa.w>bb.w;
}
int find(int x)
{
return set[x]==x?x:find(set[x]);
}
int merge(int x,int y)//判斷是否屬於同一個集合
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
return 1;//不屬於
return 0;//屬於
}
int Kruskal()
{
int maxx=INF;
sort(c,c+m,cmp);
for(int i=0; i<m; i++)
{
if(merge(c[i].v,c[i].u))//不屬於同一個集合
{
maxx=min(maxx,c[i].w);//更新最小值
set[find(c[i].v)]=find(c[i].u);//合併到同一集合
}
if(!merge(1,n))//判斷1、n是否在同一集合,如果在,可以直接從1~n,跳出
break;
}
return maxx;
}
void init()
{
for(int i=1; i<=n; i++)
set[i]=i;
}
int main()
{
int t,T=0;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
for(int i=0; i<m; i++)
scanf("%d%d%d",&c[i].u,&c[i].v,&c[i].w);
int ans=Kruskal();
printf("Scenario #%d:\n%d\n\n",++T,ans);
}
return 0;
}
相關推薦
POJ 1797 Heavy Transportation(最大生成樹)
題目大意:給定n個頂點,以及m條邊的描述,每條邊的描述包括:起點、終點、權重。現在要從頂點1出發到達頂點n,求路徑中能夠承受的最大權重。 解題思路:讀懂題意很重要,樣例比較水,要去深入理解題目,同時注意輸出格式。 1)本題要求出的是從頂點1到頂點n的所有可行路徑中各邊權值
poj 2377 Bad Cowtractors (最大生成樹)
Bessie has been hired to build a cheap internet network among Farmer John's N (2 <= N <= 1,000) barns that are conveniently numbe
POJ-1797 Heavy Transportation(最短路變形)
Heavy Transportation Time Limit: 3000MS Memory Limit: 30000K Total Submissions:
Heavy Transportation【最大生成樹】
Heavy TransportationTime Limit: 3000MSMemory Limit: 30000KTotal Submissions: 43148Accepted: 11340DescriptionBackground Hugo Heavy is happy
Bad Cowtractors(最大生成樹)
found ins -m 普裏姆算法 卡爾 eal following void HR Description Bessie has been hired to build a cheap internet network among Farmer John
POJ 1797 Heavy Transportation 【最短路思維+最大承載】
The first line contains the number of scenarios (city plans). For each city the number n of street crossings (1 <= n <= 1000) and number m of stree
poj 1797Heavy Transportation(最大生成樹)
Heavy Transportation Time Limit: 3000MS Memory Limit: 30000K
貨車運輸(最大生成樹+LCA)
整數 fine std 一個 ext getchar() 最小路徑 ont getch 題目描述 A 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物, 司機們想知道每輛車在不超過車輛限重
ACM_他和她(最大生成樹+最短路徑)
遇到 否則 ret 所有 end 接下來 這樣的 機房 那種 他和她 Time Limit: 2000/1000ms (Java/Others) Problem Description: 大二上學期剛過完,平時成績不錯的小V參加了一個小型編程比賽,遇到一道題,雖然
「NOIP2013」「LuoguP1967」貨車運輸(最大生成樹 倍增 LCA 「LuoguP4180」 【模板】嚴格次小生成樹[BJWC2010](倍增 LCA Kruscal
題目描述 AA國有nn座城市,編號從 11到nn,城市之間有 mm 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 qq 輛貨車在運輸貨物, 司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。 輸入輸出格式 輸入格式: &nb
「NOIP2013」「LuoguP1967」貨車運輸(最大生成樹 倍增 LCA
!= noi ora 輸出 tdi ott 限制 格式 否則 題目描述 AA國有nn座城市,編號從 11到nn,城市之間有 mm 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 qq 輛貨車在運輸貨物, 司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重
貨車運輸(最大生成樹+樹上倍增)
題目描述 A 國有 n n n 座城市,編號從
BZOJ4736 溫暖會指引我們前行(動態樹+最大生成樹)
類似於瓶頸路,滿足條件的路徑一定在溫度的最大生成樹上,那麼就是一個LCT維護MST的裸題了。 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #includ
poj-2377模板題,最大生成樹
Bessie has been hired to build a cheap internet network among Farmer John's N (2 <= N <= 1,000) barns that are conveniently numbered
【NOIP 2013 Day1 T3】貨車運輸(最大生成樹+LCA)
題目描述 Description A 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。
POJ-1797 Heavy Transportation(最大生成樹)
ngs accept source total project tween task father then Heavy Transportation Time Limit: 3000MS Memory Limit: 30000K Total Submiss
【最多能夠承受的最大重量】poj 1797 Heavy Transportation
Problem Description 輸入T組測試資料,每組測試資料,輸入n,m分別代表n個城市,m條道路接下來m行,每行u,v,w分別代表u,v兩城市之間道路承受的重量。 思路:讓你求出從城市1到城市n最多能夠運輸最大重量,最短路的演算法,改變下
POJ--1797 Heavy Transportation (最短路)
題目電波: POJ--1797 Heavy Transportation n點m條邊, 求1到n最短邊最大的路徑的最短邊長度 改進dijikstra,dist[i]陣列儲存源點到i點的最短邊最大的路徑的最短邊長度 #include<iostrea
(poj 2377)Kruskal演算法 最大生成樹
這道題只是一道模板題,感到唯一的坑點就是n,m容易打錯,一定要注意結構體要開到Max(M)+n; 之前便是因為這個地方Runtime Error了兩次;順便注意最後輸出的答案 為long long型 Kruskal演算法通過把所有的邊從小到大排列後,不斷取權值最
Poj 1797 Heavy Transportation (最短路變形)
題意:給你一張圖,有n個點,m條邊。讓你求出從1點到n點的所有通路中最小邊的最大值。 題解:最短路的變形。把dijkstra中dis陣列中存的東西改成最小邊的最大值。每次找最大邊來作比較。然後更新di