传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1202
很显然这道题就是给定n个数,m个区间和,问是否合法
线性规划显然,x_i表示每个数的值,约束就是区间和,由于可能出现负数,所以每一个都要加一个叫较大的正值,用线性规划的初始化判断可行性就好了,
不过这样会T……只有60分,T的原因在于建立线性规划的式子太费时了
于是优化成前缀和的形式,如果[l,r]的和为v,那么x_r-x_{l-1}=v,拿来数据一测,7s A了,交在bzoj上却T了……找了台linux自测,A了……然后就各种蛋疼……
忽然想到改成前缀和的形式不就差分约束吗……可行性判负环不就好了……………………
60分线性规划:
#include<bits/stdc++.h> using namespace std; const int maxn=2100; const int maxm=110; const double eps=1e-6; double a[maxn][maxm]; int n,m; int dcmp(double x){ if(fabs(x)<eps)return 0; return x>0?1:-1; } double simplex(bool f); void pivot(int l,int e,bool f){ for(int i=0;i<=m+f;i++){ if(i==e)continue; a[l][i]/=a[l][e]; }a[l][e]=1/a[l][e]; for(int i=0;i<=n+f;i++){ if(i==l)continue; for(int j=0;j<=m+f;j++){ if(j==e)continue; a[i][j]-=a[i][e]*a[l][j]; }a[i][e]*=-a[l][e]; } } bool init(){ int pos=-1; double minn=1e300; for(int i=1;i<=n;i++) if(dcmp(minn-a[i][0])==1)minn=a[i][0],pos=i; if(dcmp(minn)>=0)return 1; for(int i=0;i<=m;i++)swap(a[0][i],a[n+1][i]); for(int i=0;i<=n;i++)a[i][m+1]=-1; pivot(pos,m+1,1); if(!dcmp(simplex(1))){ for(int i=1;i<=m+1;i++)if(!dcmp(a[0][i]+1)){pos=i;break;} for(int i=0;i<=m+1;i++)swap(a[0][i],a[n+1][i]); for(int i=0;i<=n+1;i++)swap(a[i][pos],a[i][m+1]); }else return 0; return 1; } double simplex(bool f){ for(;;){ int pos=-1,l,e; double minn=0; for(int i=1;i<=m+f;i++) if(dcmp(a[0][i]-minn)==1)minn=a[0][i],pos=i; if(!~pos)return -a[0][0]; e=pos;pos=-1;minn=1e300; for(int i=1;i<=n;i++) if(dcmp(a[i][e])==1&&dcmp(a[i][0]/a[i][e]-minn)==-1) minn=a[i][0]/a[i][e],pos=i; if(!~pos){ printf("INF!!\n"); return 1e300; }l=pos; pivot(l,e,f); } } int T; int main(){ // freopen("123.txt","w",stdout); scanf("%d",&T); while(T--){ scanf("%d%d",&m,&n); int now=0; int l,r,v; memset(a,0,sizeof(a)); for(int j=1;j<=n;j++){ scanf("%d%d%d",&l,&r,&v); for(int i=l;i<=r;i++){ a[0][i]=1; a[now+1][i]=1; a[now+2][i]=-1; } a[now+1][0]=v+(r-l+1)*5e2; a[now+2][0]=-v-(r-l+1)*5e2; now+=2; } n+=n; if(init())puts("true"); else puts("false"); } return 0; }
#include<bits/stdc++.h> using namespace std; const int maxn=3011; const int maxm=101; const double eps=1e-2; double a[maxn][maxm]; int n,m; int dcmp(double x){ if(fabs(x)<eps)return 0; return x>0?1:-1; } double simplex(bool f); void pivot(int l,int e,bool f){ for(int i=0;i<=m+f;i++){ if(i==e)continue; a[l][i]/=a[l][e]; }a[l][e]=1/a[l][e]; for(int i=0;i<=n+f;i++){ if(i==l)continue; for(int j=0;j<=m+f;j++){ if(j==e)continue; a[i][j]-=a[i][e]*a[l][j]; }a[i][e]*=-a[l][e]; } } bool init(){ int pos=-1; double minn=1e300; for(int i=1;i<=n;i++) if(dcmp(minn-a[i][0])==1)minn=a[i][0],pos=i; if(dcmp(minn)>=0)return 1; for(int i=0;i<=m;i++)swap(a[0][i],a[n+1][i]); for(int i=0;i<=n;i++)a[i][m+1]=-1; pivot(pos,m+1,1); if(!dcmp(simplex(1))){ for(int i=1;i<=m+1;i++)if(!dcmp(a[0][i]+1)){pos=i;break;} for(int i=0;i<=m+1;i++)swap(a[0][i],a[n+1][i]); for(int i=0;i<=n+1;i++)swap(a[i][pos],a[i][m+1]); }else return 0; return 1; } double simplex(bool f){ for(;;){ int pos=-1,l,e; double minn=0; for(int i=1;i<=m+f;i++) if(dcmp(a[0][i]-minn)==1)minn=a[0][i],pos=i; if(!~pos)return -a[0][0]; e=pos;pos=-1;minn=1e300; for(int i=1;i<=n;i++) if(dcmp(a[i][e])==1&&dcmp(a[i][0]/a[i][e]-minn)==-1) minn=a[i][0]/a[i][e],pos=i; if(!~pos){ printf("INF!!\n"); return 1e300; }l=pos; pivot(l,e,f); } } template<typename T> T getint(){ T rs=0,f=1;char c=getchar(); while(!isdigit(c))f=f==-1||c=='-'?-1:1,c=getchar(); while(isdigit(c))rs=(rs<<3)+(rs<<1)+c-'0',c=getchar(); return rs*f; } int T; int main(){ // freopen("123.txt","w",stdout); scanf("%d",&T); while(T--){ m=getint<int>(); n=getint<int>(); int now=0; int l,r,v; memset(a,0,sizeof(a)); for(int j=1;j<=n;j++){ l=getint<int>(); r=getint<int>(); v=getint<int>(); a[now+1][r]=1; a[now+1][l-1]=-1; a[now+2][r]=-1; a[now+2][l-1]=1; a[now+1][0]=v+(r-l+1)*5e2; a[now+2][0]=-v-(r-l+1)*5e2; now+=2; } n+=n; if(init())puts("true"); else puts("false"); } return 0; }
#include<bits/stdc++.h> using namespace std; const int maxn=110; vector<pair<int,int> >G[maxn]; void add(int u,int v,int w){ G[u].push_back(pair<int,int>(v,w)); G[v].push_back(pair<int,int>(u,-w)); } int n,m,T; int d[maxn],vis[maxn],in[maxn]; bool spfa(){ memset(d,0x7f,sizeof(d)); memset(vis,0,sizeof(vis)); memset(in,0,sizeof(in)); d[0]=0; queue<int>q; q.push(0);vis[0]=1; while(!q.empty()){ int u=q.front();q.pop();vis[u]=0; for(int i=0;i<G[u].size();i++){ int v=G[u][i].first,w=G[u][i].second; if(d[v]>d[u]+w){ d[v]=d[u]+w; if(!vis[v]){ vis[v]=1; q.push(v); if(++in[v]>n)return 0; } } } }return 1; } int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); for(int i=0;i<=n;i++)G[i].clear(); for(int j=1;j<=m;j++){ int l,r,v; scanf("%d%d%d",&l,&r,&v); add(l-1,r,v); } if(spfa())puts("true"); else puts("false"); } return 0; }