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