4022农夫喂牛 |
难度级别:D; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B |
试题描述
|
农夫老张养了N头牛,编号分别从1到N。现在,它们要“用餐”,按照编号顺序排成一排,在它们之间有一些牛关系比较好,希望彼此之间不超过一定距离,也有些牛关系不太好,希望彼此之间至少要隔开一定距离。此外,有的牛性格比较犟,可能出现多头挤在一起的情况。给出ML个关系好的牛的信息(AL,BL,DL),MD个关系不好的牛的信息(AD,BD,DD),表示牛AL和牛BL之间的最大距离为DL,牛AD和BD之间的最小距离为DD。在满足这些条件的排列方法中,求1号牛和N号牛之间的最大距离。如果不存在任何一种排列方法满足条件则输出-1.超过10^9的情况输出-2. |
输入
|
第一行包括三个数N,ML和MD,接下来的ML行,每行三个数分别为AL,BL和DL,再接下来的MD行,每行三个数,分别为AD,BD和DD。各行的数两两之间用一个空格分隔。
|
输出
|
输出符合题目要求的一个数。
|
输入示例
|
4 2 1
1 3 10 2 4 20 2 3 3 |
输出示例
|
27
|
其他说明
|
数据范围:1<N<=1000,0<ML,MD<=10000,0<AL<BL<=N,0<AD<BD<=N,0<DL,DD<=1000000。
|
题解:呵呵哒差分约束。。。
ML S[b]-S[a]<=c
MD S[b]-S[a]>=c 转化后 S[a]-S[b]<=-c
还有相邻的两只牛之间的距离 S[i]-s[i-1]>=0 转化后 S[i-1]-S[i]<=0
我们要求最长的排队距离就是要解出这个关系 S[N]-S[1]<=x,这里可以发现约束已经符合标准,从1指向n 就是以1为源点求1到n的最短路。
我当时还各种YY区间贪心神马的。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar(' ') 9 using namespace std; 10 const int maxn=1000+10,maxm=30000+10,inf=1e9; 11 struct ted{int x,y,w;ted*nxt;}adj[maxm],*fch[maxn],*ms=adj;int n; 12 void add(int x,int y,int w){ 13 *ms=(ted){x,y,w,fch[x]};fch[x]=ms++;return; 14 } 15 bool inq[maxn];int d[maxn],cnt[maxn]; 16 int spfa(){ 17 queue<int>Q; 18 for(int i=0;i<=n;i++)d[i]=inf; 19 Q.push(1);d[1]=0;cnt[1]=1; 20 while(!Q.empty()){ 21 int x=Q.front();Q.pop();inq[x]=false; 22 for(ted*e=fch[x];e;e=e->nxt){ 23 int v=e->y; 24 if(d[v]>d[x]+e->w){ 25 d[v]=d[x]+e->w; 26 if(!inq[v]){ 27 inq[v]=true;Q.push(v); 28 if(++cnt[v]>n)return -1; 29 } 30 } 31 } 32 }if(d[n]==inf)return -2;return d[n]; 33 } 34 inline int read(){ 35 int x=0,sig=1;char ch=getchar(); 36 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();} 37 while(isdigit(ch))x=10*x+ch-'0',ch=getchar(); 38 return x*=sig; 39 } 40 inline void write(int x){ 41 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 42 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 43 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 44 } 45 void init(){ 46 int ML,MD,from,to,len; 47 n=read();ML=read();MD=read(); 48 while(ML--){ 49 from=read();to=read();len=read();add(from,to,len); 50 } 51 while(MD--){ 52 from=read();to=read();len=read();add(to,from,-len); 53 } 54 for(int i=1;i<=n;i++)add(i,i-1,0); 55 write(spfa());ENT; 56 return; 57 } 58 void work(){ 59 return; 60 } 61 void print(){ 62 return; 63 } 64 int main(){init();work();print();return 0;}