POJ 1797 Heavy Transportation(最大生成树)

题目链接:http://poj.org/problem?id=1797

题目大意:给定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
#include
#include
#include
#include
#include
#include
#include
#include
#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;iminn)
          {
              minn=dis[j];
              pos=j;
          }
        }
        vis[pos]=1;
        for(int j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]

prim算法:

#include
#include
#include
#include
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;iminn)
            {
                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]

Kruskal:

#include
#include
#include
#include
#include
#include
#include
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

你可能感兴趣的:(习题集)