题目链接:http://poj.org/problem?id=1797
题目大意:给出一个无向图,然后每条路都有自己的承重限制,问从 点1 到 点n ,找到一条道路使得这条道路所承受的重量最大,然后输出这个最大承重。
思路:一开始以为是最大生成树,但是写到一半之后发现不对劲。。结果后来再看看题,发现可以用最大流来解决,求出最大的增光路就行了,注意一下是无向图。(补充,我看讨论区好像都是用最大生成树写的,汗...有时间在补一补这个最大生成树吧..我觉得我已经凉了...)
AC(求增光路):(交C++还编译错误,我不就是五六个Warning么...只有G++才行...)
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define Pair pair<int,int>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
// register
const int MAXN=1e6+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
struct node{
int v,w,cost,nxt;
node(int _v=0,int _w=0,int _nxt=0):
v(_v),w(_w),nxt(_nxt){}
}edge[MAXN];
int head[MAXN],ecnt;
int dis[MAXN];
int n,m,s,t;
void intt(){
clean(head,-1);
ecnt=0;
}
void add(int u,int v,int w){
edge[ecnt]=node(v,w,head[u]);
head[u]=ecnt++;
edge[ecnt]=node(u,w,head[v]);
head[v]=ecnt++;
}
int bfs(){
int res=0;
clean(dis,0);
queue<Pair > que;que.push({s,INF32});
while(que.size()){
Pair u=que.front();que.pop();
if(u.first==t){
res=max(res,u.second);
continue;
}
for(int i=head[u.first];i+1;i=edge[i].nxt){
int temp=edge[i].v,val=min(edge[i].w,u.second);
if(dis[temp]<val){
dis[temp]=val;
que.push({temp,val});
}
}
}return res;
}
int main(){
int T,Case=1;
scanf("%d",&T);
while(T--){
intt();
scanf("%d%d",&n,&m);
int a,b,val;
for(int i=1;i<=m;++i){
scanf("%d%d%d",&a,&b,&val);
add(a,b,val);
}s=1,t=n;
printf("Scenario #%d:\n%d\n\n",Case++,bfs());
}
}
果然我还是想用最大生成树来写一写。。就来写了。。
思路还是那个想法,就是得出最大生成树,然后搜索上面的最小的边权就行了。。(整天水题。。我自己都快看不下去了。。)
AC:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define Pair pair<int,int>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
// register
const int MAXN=1e3+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
int mp[MAXN][MAXN];
int vis[MAXN],dis[MAXN];
int pre[MAXN];
int n,m;
void Prime(){
for(int i=1;i<MAXN;++i){
pre[i]=i;
dis[i]=vis[i]=0;
}
for(int i=1;i<=n;++i){
int can=-1,maxx=-1;
for(int j=1;j<=n;++j){
if(vis[j]==0&&maxx<dis[j]){
maxx=dis[j];
can=j;
}
}vis[can]=1;
for(int j=1;j<=n;++j){
if(vis[j]==0&&mp[can][j]>dis[j]){
dis[j]=mp[can][j];
pre[j]=can;
}
}
}
}
int Solve(){
clean(vis,0);
vector<int> vec[MAXN];
for(int i=1;i<=n;++i){
if(pre[i]!=i){
vec[i].push_back(pre[i]);
vec[pre[i]].push_back(i);
}
}
queue<Pair > que;
que.push({1,INF32});
while(que.size()){
Pair e=que.front();que.pop();
if(e.first==n) return e.second;
int len=vec[e.first].size();
for(int i=0;i<len;++i){
int temp=vec[e.first][i];
if(vis[temp]==0){
que.push({temp,min(mp[e.first][temp],e.second)});
vis[temp]=1;
}
}
}
}
int main(){
int Case=1,T;
scanf("%d",&T);
while(T--){
clean(mp,0);
scanf("%d%d",&n,&m);
int a,b,val;
for(int i=1;i<=m;++i){
scanf("%d%d%d",&a,&b,&val);
if(mp[a][b]<val) mp[a][b]=mp[b][a]=val;
}
Prime();//获得最大生成树.
printf("Scenario #%d:\n%d\n\n",Case++,Solve());
}
}