vijos1027题解

题目:

当大家在考场中接受考验(折磨?)的时候,小呆正在悠闲(欠扁)地玩一个叫“最初梦想”的游戏。游戏描述的是一个叫pass的有志少年在不同的时空穿越对抗传说中的大魔王chinesesonic的故事。小呆发现这个游戏的故事流程设计得很复杂,它有着很多的分支剧情,但不同的分支剧情是可以同时进行的,因此游戏可以由剧情和剧情的结束点组成,某些剧情必须要在一些特定的剧情结束后才能继续发展。为了体验游戏的完整性,小呆决定要看到所有的分支剧情——完成所有的任务。但这样做会不会耽误小呆宝贵的睡觉时间呢?所以就请你来解决这个问题了。小呆会给你一个剧情流程和完成条件的列表,其中第一行有一个数n(0<n<100),表示总共有n个剧情结束点,第二行一个数m(0<m<=120),表示由m个不同的剧情,下面的m行中每行有三个数i(0<i<=100),j(0<j<=100),k(0<k<=1000),表示从剧情结束点i必须完成一个耗费时间为k的剧情才能到达剧情结束点j。注意,这m行中出现的1不是剧情结束点而是游戏的开始,而n+1表示游戏结束。你要告诉小呆完成整个游戏至少需要多少时间以及要经过的所有可能的剧情结束点(按升序输出)。

这道题纯粹是语文题(什么时候让HHD去做做O(∩_∩)O~~)

好不容易看懂了题目的意思:求最长路并打印路径。
在编floyd的时候(数据弱,这个也可以了),忽然忘了怎么加路径。
赶紧百度一下,哦,总算有些想起来(就是下文当中的out函数)。
样例通过后,赶紧提交:WA了两个点!什么情况?
怎么也想不出,偷偷去看了题解(你什么都不知道,俺可是正大光明的)
原来,可能有多条最长路径,所以要升序输出所有路径!!!!!!!!

又改了一下就A了,这样,那个辛辛苦苦做的out函数反而没调用。

#include<stdio.h>
using namespace std;
long f[101][101],i,j,k,x,y,z,n,m,pre[101][101];
void out(long l,long r)
{
  if (pre[l][r]==0) return;
  out(l,pre[l][r]);
  printf("%ld ",pre[l][r]);
  out(pre[l][r],r);
}
int main()
{
    scanf("%ld",&n);n++;
    scanf("%ld",&m);
    for (i=1;i<=n;i++)
      for (j=1;j<=n;j++)
        f[i][j]=0;
    for (i=1;i<=m;i++)
      {
        scanf("%ld %ld%ld",&x,&y,&z);
        f[x][y]=z;
      }
    for (k=1;k<=n;k++)
      for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)
          if((i!=j)&&(i!=k)&&(j!=k)&&(f[i][k]>0)&&(f[k][j]>0)&&(f[i][k]+f[k][j]>f[i][j]))
            {
             f[i][j]=f[i][k]+f[k][j];
             //pre[i][j]=k;
            }
    printf("%ld\n",f[1][n]);
    printf("1 ");
    for (i=2;i<n;i++)
      if (f[1][i]+f[i][n]==f[1][n]) 
        printf("%ld ",i);
    //out(1,n);
    printf("%ld",n);
    return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值