时间: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;}