Cow Relays

Description

For their physical fitness program, N (2 <= N <= 1,000,000) cows have decided to run a relay race using the T (2 <= T <= 100) cow trails throughout the pasture.

Each trail connects two different intersections (1 <= I1i <= 1,000; 1 <= I2i <= 1,000), each of which is the termination for at least two trails. The cows know the lengthi of each trail (1 <=lengthi <= 1,000), the two intersections the trail connects, and they know that no two intersections are directly connected by two different trails. The trails form a structure known mathematically as a graph.

To run the relay, the N cows position themselves at various intersections (some intersections might have more than one cow). They must position themselves properly so that they can hand off the baton cow-by-cow and end up at the proper finishing place.

Write a program to help position the cows. Find the shortest path that connects the starting intersection (S) and the ending intersection (E) and traverses exactly N cow trails.

Input

Line 1:        Four space-separated integers: NTS, and E
Lines 2..T+1:  Line i+1 describes trail i with three space-separated integers: lengthi , I1i , and I2i

Output

Line 1:     A single integer that is the shortest distance from intersection S  to intersection E  that traverses exactly N  cow trails.

Sample Input

2 6 6 4
11 4 6
4 4 8
8 4 9
6 6 8
2 6 9
3 8 9

Sample Output

10

问题:给出起点和终点!在有限条边的情况下!求出其起点到终点的最短路径(注意,可以跑回头!)!我们在这可以用floyd的思想来做!不过其时间复杂度为O(N^3),太长并且可能我的能力吧!没得剪枝!

Floyd的核心:

For(k=1;k<=n;k++)
{

For(i=1;i<=n;i++)
   {

    For(j=1;j<=n;j++)
       {

         Map[i][j]=min(map[i][j],map[i][k]+map[k][j]);

    }

}

}

基本思想就是这样!然后就是用矩阵来表示;调用了k次floyd之后ans[S][T]就是所求的解!

代码:在poj过了在我们学校的oj却TLE;

#include"stdio.h"

#include"string.h"

#define inf 1000000001

#define maxn 1005

int K,M,S,T,v[maxn],cnt,map[maxn][maxn],used[maxn];

int ans[maxn][maxn],dis[maxn][maxn],tmp[maxn][maxn];

void floyd(int c[][maxn],int a[][maxn],int b[maxn][maxn])

{

       int i,j,k;

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

          {

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

                       {

                     for(j=0;j<cnt;j++)

                                    {

                            if(c[v[i]][v[j]]>a[v[i]][v[k]]+b[v[k]][v[j]])

                                   c[v[i]][v[j]]=a[v[i]][v[k]]+b[v[k]][v[j]];

                     }

              }

       }

}

void copy(int a[][maxn],int b[][maxn])

{

       int i,j;

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

       {

              for(j=0;j<cnt;j++)

              {

                     a[v[i]][v[j]]=b[v[i]][v[j]];

                     b[v[i]][v[j]]=inf;

              }

       }

}

void solve(int k)

{

       while(k)

       {

              if(k%2)

              {

                     floyd(dis,ans,map);

                     copy(ans,dis);

              }

              floyd(tmp,map,map);

              copy(map,tmp); 

              k=k/2;

       }

}

int main()

{

       int i,j;

       int x,y,val;

       while(scanf("%d%d%d%d",&K,&M,&S,&T)==4)

       {

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

              {

                     for(j=0;j<=1001;j++)

                     {

                            map[i][j]=inf;

                            ans[i][j]=inf;

                            tmp[i][j]=inf;

                            dis[i][j]=inf;

                     }

                     ans[i][i]=0;

              }

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

              cnt=0;

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

              {

                     scanf("%d%d%d",&val,&x,&y);

                     if(map[x][y]>val)

                     {

                            map[x][y]=val;

                            map[y][x]=map[x][y];

                     }

                     if(!used[x])

                     {

                            used[x]=1;

                            v[cnt++]=x;

                     }

                     if(!used[y])

                     {

                            used[y]=1;

                            v[cnt++]=y;

                     }

              }

              solve(K);

              printf("%d\n",ans[S][T]);

       }

       return 0;

}

转载于:https://www.cnblogs.com/adroitly/archive/2012/07/31/2616703.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值