由poj 1125,poj 1062解析最短路径

poj 1125,poj 1062解析最短路径

一、poj 1125(有向图,未定义起始点和终点)

题意:给出一个图,点表示人,边表示消息从这个人传到另一个人所花的时间,你的任务是求把消息告诉里面的哪一个人(假设你只能告诉一个人),能让消息遍布整个网络所花的最少时间,并求最少时间。

//这个题目题意比题解难。。。。

题解:首先从n个人中选择一个人,把消息告诉他,然后用一个求单源最短路径算法求出其他所有人收到消息的最短时间,然后最大的最短时间就是消息遍布整个网络所花的最少时间。然后再在n个最少时间中选出最少的,即是答案。

 

#include<stdio.h>

#define inf 10000

int dij();

int n,i,k,t,d[101],e[101][101],max1,max2,used[101],m;

int main(){

while(~scanf("%d",&n),n)

{ for(i=0;i<n;i++)

for(k=0;k<n;k++)

{e[i][k]=inf;d[i]=inf;}

max1=10000,max2=0,m=1111;

for(i=0;i<n;i++)

{

scanf("%d",&k);

while(k--)

{ scanf("%d",&t);

scanf("%d",&e[i][t-1]);

}

}

{for(k=0;k<n;k++) printf("%d    ",e[i][k]); printf("\n"); }*/

for(i=0;i<n;i++)

{

max2=dij(i);

if(max2<max1) {max1=max2;m=i+1;}

}

printf("%d %d\n",m,max1);

}

}

int dij(int s){ int v,u,max=0;

memset(used,0,sizeof(used));

for(u=0;u<n;u++)

d[u]=inf;

d[s]=0;

 

 

while(1)

{ v=-1;

for(u=0;u<n;u++)

{ if(!used[u]&&(v==-1||d[u]<d[v]))

v=u;

}

if(v==-1) break;

used[v]=1;

for(u=0;u<n;u++)

if(d[u]>d[v]+e[v][u])

d[u]=d[v]+e[v][u];

if(v!=s&&d[v]>max) max=d[v];

}// printf("%d**\n",max);

return max;

}

二、poj1062(有向图,定义了起始点和终点,但对路径有要求)

难得的中文题,题目见http://poj.org/problem?id=1062

模拟出图,可设村夫所在起始点为0点,如直接到1点(酋长的许诺),需要花费10000,即0,1两点边权为10000.

此题难点在于对路径的要求

方法一:对路径进行枚举

假设某一点为最高权限点,把权限比他高的点以及与它权限差超过限制条件的点舍弃,再对剩余点求最短路径。

方法二:递归求最短路(需要是有向图)

#include<stdio.h>

#define inf 1<<30

int M,N,i,k,d[101][101],a[101],vis[101],MIN=inf,t,ds[101];void dfs();

int main(){ memset(a,0,sizeof(a));

memset(vis,0,sizeof(vis));

scanf("%d%d",&M,&N);

for(i=0;i<=N;i++)

for(k=0;k<=N;k++)

{d[i][k]=inf;ds[i]=inf;}

for(i=1;i<=N;i++)

{ scanf("%d%d%d",&d[0][i],&a[i],&k);

ds[i]=d[0][i];

while(k--)

{

scanf("%d",&t);

scanf("%d",&d[t][i]);

}

}

dfs(1,a[1],a[1]);

printf("%d\n",ds[1]);

return 0;}

 

 

void dfs(int v ,int maxl , int minl){ int u;

int max,min;

    if(vis[v]) return ;

    vis[v]=1;

    

    for(u=1; u<=N; u++) if(d[u][v]!=inf) //有边

    {

        max=maxl>a[u]?maxl:a[u];

        min=minl<a[u]?minl:a[u];

        if(max-min<=M)  //在路径中任意点的等级差不能超过M

        {

            dfs(u,max,min);

            if(d[u][v]+ds[u]<ds[v])

                ds[v]=d[u][v]+ds[u];

 

        }

    }

    

    return;}

 

 //此题搜索可做,但超时也是肯定的

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值