时间:2016-04-02 19:42:38 星期六
题目编号:[2016-04-02][POJ][1797][Heavy Transportation]
题目大意:给定一个图,求起点1到终点n的所有路径中,最大承重值,即所有路径中,承重的最小值的最大值
分析:
方法1:Dijkstra
- 跑一次Dijkstra,d[v] = max(d[v],min(d[u],a[u][v]));
- 初始条件:d[s] = INF;
- 每次应该选择大的点\
- 这里没判断边是否存在也能过,不过时间是判断了的 5倍
方法2:并查集,最小生成树(此题是最大生成树)
//Dijkstra
#include <queue>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 1000 + 10;
const int maxm = maxn * maxn / 2;
struct Node{
int v,c;
Node(int _v = 0,int _c = 0):v(_v),c(_c){}
bool operator < (const Node & a)const {
return c < a.c;
}
};
int vis[maxn],d[maxn],a[maxn][maxn],n,m;
void Dijkstra(int s){
memset(vis,0,sizeof(vis));
memset(d,0x3f,sizeof(d));
priority_queue<Node> q;
d[s] = 0x3f3f3f3f;
q.push(Node(s,0));
Node tmp;
while(!q.empty()){
tmp = q.top();q.pop();
int u = tmp.v;
if(vis[u]) continue;
vis[u] = 1;
for(int i = 1 ; i <= n ; ++i){
if(!vis[i] &&a[u][i]){
d[i] = max((d[i]==0x3f3f3f3f?-1:d[i]),min(d[u],a[u][i]));
q.push(Node(i,d[i]));
}
}
}
}
int main(){
int cntcase = 0,_a,b,c;
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
memset(a,0,sizeof(a));
for(int i = 0;i < m ; ++i){
scanf("%d%d%d",&_a,&b,&c);
a[_a][b] = a[b][_a] = c;
}
Dijkstra(1);
printf("Scenario #%d:\n",++cntcase);
printf("%d\n\n",d[n]);
}
return 0;
}
//并查集
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 1000 + 10;
const int maxm = maxn * maxn / 2;
int fa[maxn];
struct Point{
int x,y;
}p[maxn];
struct Edge{
int u,v,c;
Edge(int _u = 0,int _v = 0,int _c = 0):u(_u),v(_v),c(_c){}
bool operator < (const Edge & a)const{
return c > a.c;
}
}e[maxm];
void ini(int n){
for(int i = 0;i <= n ; ++i){
fa[i] = i;
}
}
int fnd(int x){
return fa[x] == x?x:fa[x] = fnd(fa[x]);
}
int n,m;
int main(){
int cntcase = 0;
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i = 0;i < m ; ++i){
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].c);
}
sort(e,e+m);
int ans = 0x3f3f3f3f,f1,f2;
ini(n);
for(int i = 0;i < m ; ++i){
f1 = fnd(e[i].u);
f2 = fnd(e[i].v);
if(f1 != f2){
fa[f1] = f2;
ans = min(ans,e[i].c);
}
if(fnd(1) == fnd(n)) break;
}
printf("Scenario #%d:\n",++cntcase);
printf("%d\n\n",ans);
}
return 0;
}