月亮之眼_KEY

问题描述

吉儿是一家古董店的老板娘,由于她经营有道,小店开得红红火火。昨天,吉儿无意之中得到了散落民间几百年的珍宝——月亮之眼。吉儿深知“月亮之眼”价值连城:它是由许多珍珠相连而成的,工匠们用金线连接珍珠,每根金线连接两个珍珠;同时又对每根金线染上两种颜色,一半染成银白色,一半染成黛黑色。由于吉儿自小熟读古籍,所以还晓得“月亮之眼”的神秘传说: “月亮之眼”原是一个古代寺庙的宝物,原本是挂在佛堂的一根顶梁柱上的,整个宝物垂直悬挂,所有珍珠排成一线,且都镶嵌在柱子里,而每一根金线又都是绷紧的,并且金线的银白色一端始终在黛黑色一端的上方;然而,在一个月圆之夜, “月亮之眼”突然从柱里飞出,掉落下来,宝物本身完好无损,只是僧侣们再也无法以原样把“月亮之眼”嵌入柱子中了。吉儿望着这个神秘的宝物,回忆着童年读到的传说,顿时萌发出恢复“月亮之眼”的冲动,但是摆弄了几天依旧没有成功。为了把“月亮之眼”还原,吉尔拜访了 P 个僧侣,每个僧侣根据自己的回忆告诉给了一些有关的信息,主要是描述某两个珍珠之间的距离。

例如根据回忆,1 号珍珠到 5 号珍珠的距离是 10,其中 1 号这头是银白色金线,5 号这头是黛黑色金线。你要设计一个程序,对于给定的“月亮之眼”进行周密分析,然后给出这串宝物几百年前嵌在佛堂顶梁柱上的排列模样(各个珍珠在顶梁柱上的位置),珍珠的大小忽略不计。

输入格式

第一行有两个整数 N 和 P, 其中 N 表示宝物中的珍珠个数, P 表示有 P 个僧侣的句子,对金线的一些描述;

以下 P 行描述珍珠连接情况:第 i+1 行有三个整数,Ri1,Ri2,Li。其中 Ri1 表示第 i 根金线的银白色一端连接的珍珠序号;Ri2 表示第 i 根金线的黛黑色一端连接的珍珠序号;Li 表示第 i 根金线的长度。

输出格式

输出文件共 N 行:
第 i 行一个整数 S,它表示标号为 i 的珍珠在顶梁柱上距离最高位置珍珠的距离。
若无解则输出仅一行,包含一个整数“-1” 。

输入样例

9 9
1 2 3
2 3 5
2 7 1
4 5 4
5 6 1
5 9 1
6 7 1
7 8 3
9 8 4

输出样例

2
5
10
0
4
5
6
9
5

样例解释

最上面的是 4 号,它距离自己的距离是 0;其次是 1 号,它距离 4 号的距离是 2;再其次是 5 号,它距离 4 号的距离是 4…

数据规模

对于 30%的数据: 1≤N≤50;1≤P≤100;
对于 50%的数据: 1≤N≤100;1≤P≤150;
对于 100%的数据:1≤N≤250;1≤P≤250;1≤Ri1,Ri2≤N;1≤Li≤N;

把每个点之间的距离x到y赋值为c,y到x赋值为-c,做floyed。

另外加各种特判-1.

#include <bits/stdc++.h>
#define mx 1061109567
using namespace std;
int f[251][251],n,m;
int main(){
    scanf("%d%d",&n,&m);
    memset(f,63,sizeof(f));
        for(int i=1;i<=m;i++){
            int x,y,c;
            scanf("%d%d%d",&x,&y,&c);
            if(f[x][y]!=mx&&f[x][y]!=-c ||f[y][x]!=mx&&f[y][x]!=c){printf("-1");return 0;}\\判断是否有重边或相反边
            f[x][y]=-c;
            f[y][x]=c;
        }
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)if(i!=k)
                for(int j=1;j<=n;j++)if(i!=j&&j!=k)
                    f[i][j]=min(f[i][j],f[i][k]+f[k][j]);int w=0;
        for(int i=1;i<=n;i++){
            int o=0;
            for(int j=1;j<=n;j++){
                if(i==j)continue;
                if(f[i][j]<0)o++;
            }
            if(o==n-1&&w!=0){printf("-1");return 0;}\\点未统计完输出-1
            if(o==n-1){w=i;}
        }
        if(w==0){printf("-1");return 0;}\\没找到起始点,输出-1
        for(int i=1;i<=n;i++){
            if(i==w)printf("0\n");
            else printf("%d\n",-f[w][i]);
        }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值