hdu 1598(最小生成树变形)
2016-05-09 09:28
323 查看
解题思路:这道题我一开始的思路是动规,dp_max[i][j]表示i-j的最大边,dp_min[i][j]表示i-j的最小边,可是这样会有问题,有可能最大边与最小边不在同一条路径上,这样就很麻烦了。
正解:参考了网上的思路,这里其实是最小生成树的变形。由于是最大边与最小边的差最小,可以先把所有边按从小到大排好序,接着就是kruskal的思路了,我们把边从小到大以此加入进去,如果start和end之间有通路,那么就说明找到了一条满足要求的路径了。注意,这里由于最小边暂时是未知的,我们应该还要先去枚举最小边。这道题确实是挺难想的,如果第一次接触的话。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 205;
const int inf = 0x7ffffff;
struct Edge
{
int u,v,c;
}edge[1005];
int n,m,fa[maxn];
int find(int x)
{
if(fa[x] == x)
return x;
return fa[x] = find(fa[x]);
}
void Union(int x,int y)
{
int fx = find(x);
int fy = find(y);
if(fx != fy)
fa[fy] = fx;
}
void init()
{
for(int i = 1; i <= n; i++)
fa[i] = i;
}
bool cmp(Edge a,Edge b)
{
return a.c < b.c;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i = 0; i < m; i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].c);
sort(edge,edge+m,cmp);
int q;
scanf("%d",&q);
while(q--)
{
int ans = inf,tmp;
int start,end;
scanf("%d%d",&start,&end);
for(int i = 0; i < m; i++)
{
init();
tmp = inf;
for(int j = i; j < m; j++)
{
Union(edge[j].u,edge[j].v);
if(find(start) == find(end))
{
tmp = edge[j].c - edge[i].c;
break; //注意要break,否则tmp值会越来越大
}
}
ans = min(ans,tmp);
}
if(ans == inf) ans = -1;
printf("%d\n",ans);
}
}
return 0;
}
正解:参考了网上的思路,这里其实是最小生成树的变形。由于是最大边与最小边的差最小,可以先把所有边按从小到大排好序,接着就是kruskal的思路了,我们把边从小到大以此加入进去,如果start和end之间有通路,那么就说明找到了一条满足要求的路径了。注意,这里由于最小边暂时是未知的,我们应该还要先去枚举最小边。这道题确实是挺难想的,如果第一次接触的话。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 205;
const int inf = 0x7ffffff;
struct Edge
{
int u,v,c;
}edge[1005];
int n,m,fa[maxn];
int find(int x)
{
if(fa[x] == x)
return x;
return fa[x] = find(fa[x]);
}
void Union(int x,int y)
{
int fx = find(x);
int fy = find(y);
if(fx != fy)
fa[fy] = fx;
}
void init()
{
for(int i = 1; i <= n; i++)
fa[i] = i;
}
bool cmp(Edge a,Edge b)
{
return a.c < b.c;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i = 0; i < m; i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].c);
sort(edge,edge+m,cmp);
int q;
scanf("%d",&q);
while(q--)
{
int ans = inf,tmp;
int start,end;
scanf("%d%d",&start,&end);
for(int i = 0; i < m; i++)
{
init();
tmp = inf;
for(int j = i; j < m; j++)
{
Union(edge[j].u,edge[j].v);
if(find(start) == find(end))
{
tmp = edge[j].c - edge[i].c;
break; //注意要break,否则tmp值会越来越大
}
}
ans = min(ans,tmp);
}
if(ans == inf) ans = -1;
printf("%d\n",ans);
}
}
return 0;
}
相关文章推荐
- 初学图论-Kahn拓扑排序算法(Kahn's Topological Sort Algorithm)
- 初学图论-Bellman-Ford单源最短路径算法
- 初学图论-DAG单源最短路径算法
- 初学图论-Dijkstra单源最短路径算法
- 初学图论-Dijkstra单源最短路径算法基于优先级队列(Priority Queue)的实现
- 封装好的Folyd建图,C++源码
- LCA模板
- 图论学习笔记之一——Floyd算法
- 【LCA】SPOJ QTREE2
- poj 3249 Test for Job 最长路
- HDU 2544
- Timus 1557 Network Attack DFS+各种各种...
- HDU1289 Tarjan-模板题
- Poj2638 网络流+最短路+二分答案
- Aizu1311 分层图最短路 (...大概)
- HDU 3631 Shortest Path
- 二分图匹配模板
- 最短路径 -- spfa
- POJ2377 Bad Cowtractors
- Six Degrees of Cowvin Bacon(最短路径floyd算法)