题目大意:
牛和人一样,牛也喜欢站得离朋友较近的位置。FJ有N(2<=N<=1,000)头牛,编号为1..N,现在要设计一个顺序让他们站成一排给他们喂食。奶牛们按照编号顺序依次站立,允许有多只牛站在同一位置(也就是说,牛i和牛j(i<j)的站立位置s_i,s_j一定满足s_i<=s_j,如果s_i=s_j,那么编号为i到j之间的牛也一定站在s_i处)。
有一些牛相互喜欢,希望两牛的距离在某个范围内,同样也有一些牛相互不喜欢,希望两人的距离大于等于某个距离,题目中给出ML(1<=ML<=10,000)个限制描述相互喜欢的情况,给出MD(1<=MD<=10,000)个限制描述相互不喜欢的情况。 你的任务是计算,如果存在某种方案满足上述要求,输出1号牛和N号牛之间最大距离。解题思路:
差分约束系统。。。因为题目要求的是1和n的最大距离所以这题就跑最长路。。
对于互相反感的牛(i与j互相反感,彼此距离至少为len,i<j),就有dis[j]-dis[i]>=len。就加一条i->j,长度为len的边。 有好感的牛(i与j有好感,彼此距离至多len,i<j),就有dis[j]-dis[i]<=len;但因为我们跑的是最长路,所以得改成dis[i]-dis[j]>=-len的形式,就加一条j->i,长度-len的边。 又因为牛是按编号站成一列。。所以dis[i+1]-dis[i]>=0。也就是连一条i->i+1,长度为0的边(1<=i<n)。 如果有正权环的话就无解,如果从点n无法走到点1,也就是说n和1之间没有什么约束,那么1和n距离可以无穷大。。。 其实也可以把权值取反然后跑最短路。。虽然都一样= =源程序:
#include#include #include using namespace std;const int maxn=1023;struct zs{ int too,pre,dis;}e[23333];int last[maxn],dis[maxn],dl[maxn],tot;int i,n,m1,m2,a,b,c,l,r,now;bool u[maxn],ins[maxn],flag;int ra;char rx;void read(int &ret){ char c; ret = 0; while((c=getchar())<'0' || c>'9'); while(c>='0'&&c<='9') ret = ret*10 +(c-'0'),c=getchar();}inline void insert(int a,int b,int c) { e[++tot].too=b;e[tot].dis=c;e[tot].pre=last[a];last[a]=tot;}void dfs(int x) { ins[x]=1; for(int i=last[x],to=e[i].too;i&&!flag;i=e[i].pre,to=e[i].too)if(dis[to] b)swap(a,b); insert(b,a,-c); } for(i=1;i<=m2;i++) { read(a);read(b);read(c);if(a>b)swap(a,b); insert(a,b,c); } l=0;r=1;dl[1]=n;u[n]=1; while(l