描述
吉儿是一家古董店的老板娘,由于她经营有道,小店开得红红火火。昨天,吉儿无意之中得到了散落民间几百年的珍宝—月亮之眼。吉儿深知“月亮之眼”价值连城:它是由许多珍珠相连而成的,工匠们用金线连接珍珠,每根金线连接两个珍珠;同时又对每根金线染上两种颜色,一半染成银白色,一半染成黛黑色。由于吉儿自小熟读古籍,所以还晓得“月亮之眼”的神秘传说:“月亮之眼”原是一个古代寺庙的宝物,原本是挂在佛堂的一根顶梁柱上的,整个宝物垂直悬挂,所有珍珠排成一线,且都镶嵌在柱子里,而每一根金线又都是绷紧的,并且金线的银白色一端始终在黛黑色一端的上方;然而,在一个月圆之夜,“月亮之眼”突然从柱里飞出,掉落下来,宝物本身完好无损,只是僧侣们再也无法以原样把“月亮之眼”嵌入柱子中了。吉儿望着这个神秘的宝物,回忆着童年读到的传说,顿时萌发出恢复“月亮之眼”的冲动,但是摆弄了几天依旧没有成功。
现在,要麻烦您来帮助吉儿完成这项使命。
您要设计一个程序,对于给定的“月亮之眼”进行周密分析,然后给出这串宝物几百年前嵌在佛堂顶梁柱上的排列模样。给定的“月亮之眼”有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;
}