VIJOS 1540 月亮之眼

描述

吉兒是一家古董店的老闆娘,由於她經營有道,小店開得紅紅火火。昨天,吉兒無意之中得到了散落民間幾百年的珍寶—月亮之眼。吉兒深知“月亮之眼”價值連城:它是由許多珍珠相連而成的,工匠們用金線連接珍珠,每根金線連接兩個珍珠;同時又對每根金線染上兩種顏色,一半染成銀白色,一半染成黛黑色。由於吉兒自小熟讀古籍,所以還曉得“月亮之眼”的神祕傳說:“月亮之眼”原是一個古代寺廟的寶物,原本是掛在佛堂的一根頂樑柱上的,整個寶物垂直懸掛,所有珍珠排成一線,且都鑲嵌在柱子裏,而每一根金線又都是繃緊的,並且金線的銀白色一端始終在黛黑色一端的上方;然而,在一個月圓之夜,“月亮之眼”突然從柱裏飛出,掉落下來,寶物本身完好無損,只是僧侶們再也無法以原樣把“月亮之眼”嵌入柱子中了。吉兒望着這個神祕的寶物,回憶着童年讀到的傳說,頓時萌發出恢復“月亮之眼”的衝動,但是擺弄了幾天依舊沒有成功。

現在,要麻煩您來幫助吉兒完成這項使命。

您要設計一個程序,對於給定的“月亮之眼”進行周密分析,然後給出這串寶物幾百年前嵌在佛堂頂樑柱上的排列模樣。給定的“月亮之眼”有N個珍珠和P根金線,所有珍珠按一定順序有了一個序號:1、2…、N。

格式

輸入格式

輸入數據包含一個“月亮之眼”的特徵描述:
文件第一行有兩個整數N和P,其中N表示寶物中的珍珠個數,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

限制

1s

提示

N,P<=500

來源

Balkan OI 1998

CTSC 1999



一開始沒看懂題

後來畫個圖就明白了

讀入x,y,w

由於x必須在y上面

y必須在x下面

距離必須是w

所以建邊(y,x,w) (x,y,-w)

類似於差分約束 不過要求必須線是直的 所以距離不等於w就要更新

我按不等於就更新寫的 但是實際發現 跑最長路也可以 好奇妙的東西。。。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int lim=555;
const int inf=999999999;

struct self{int x,y,w;}s[lim<<2];
int first[lim<<2],nxt[lim<<2];
int d[lim];

queue<int>q;
bool inq[lim];
int t[lim];

int m,n,a,b,c,tall;

bool spfa()
{
    int a;
    for(a=1;a<=m;a++)q.push(a);
    while(!q.empty())
    {
        int u=q.front();q.pop();inq[u]=0;
        for(int e=first[u];e!=-1;e=nxt[e])
        if(d[s[e].y]!=d[u]+s[e].w)
        {
            d[s[e].y]=d[u]+s[e].w;
            if(!inq[s[e].y])
            {
                q.push(s[e].y);
                inq[s[e].y]=1;
                t[s[e].y]++;
                if(t[s[e].y]>m)return false;
            }
        }
    }
    return true;
}

int main()
{
    memset(first,-1,sizeof(first));memset(nxt,-1,sizeof(nxt));
    scanf("%d%d",&m,&n);
    for(a=1;a<=n;a++)
    {
        scanf("%d%d%d",&s[a].y,&s[a].x,&s[a].w);
        nxt[a]=first[s[a].x];first[s[a].x]=a;
        s[a+n].x=s[a].y;s[a+n].y=s[a].x;s[a+n].w=-s[a].w;
        nxt[a+n]=first[s[a].y];first[s[a].y]=a+n;
    }
    if(!spfa())
    {
        cout<<-1<<'\n';
        return 0;
    }
    else
    {
        for(a=1;a<=m;a++)tall=max(tall,d[a]);
        for(a=1;a<=m;a++)cout<<tall-d[a]<<'\n';
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章