差分约束模板题,差分约束是判断联立不等式组是否有解的一种方法,建图是关键。
代码:
//poj 1275 //sep9 #include <iostream> #include <queue> using namespace std; const int maxM=10024; const int maxN=32; struct Edge { int v,w,nxt; }edge[maxM]; int t[maxN],c[maxN],head[maxN],vis[maxN],inq[maxN],dis[maxN]; int e; void addedge(int u,int v,int w) { edge[e].v=v;edge[e].w=w;edge[e].nxt=head[u]; head[u]=e++; } bool spfa() { memset(inq,0,sizeof(inq)); for(int i=0;i<=24;++i) dis[i]=INT_MIN; memset(vis,0,sizeof(vis)); queue<int> Q; Q.push(0); dis[0]=0; inq[0]=1; vis[0]=1; while(!Q.empty()){ int u=Q.front();Q.pop();inq[u]=0; for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].v,w=edge[i].w; if(dis[v]<dis[u]+w){ dis[v]=dis[u]+w; if(inq[v]==0){ Q.push(v); ++vis[v]; inq[v]=1; if(vis[v]>=25) return false; } } } } return true; } int main() { int cases; scanf("%d",&cases); while(cases--){ memset(head,-1,sizeof(head)); memset(t,0,sizeof(t)); for(int i=1;i<=24;++i) scanf("%d",&c[i]); int n; scanf("%d",&n); for(int i=0;i<n;++i){ int x; scanf("%d",&x); ++t[x+1]; } int l=0,r=n+1,ans=-1,mid; while(l<r){ mid=(l+r)/2; memset(head,-1,sizeof(head)); e=0; for(int i=0;i<24;++i){ addedge(i,i+1,0); addedge(i+1,i,-t[i+1]); } addedge(0,24,mid); for(int j=1;j<=24;++j){ int i=j+8; if(i<=24) addedge(j,i,c[i]); else{ i=j+8-24; addedge(j,i,c[i]-mid); } } if(spfa()){ ans=mid; r=mid; }else{ l=mid+1; } } if(ans!=-1) printf("%d\n",ans); else puts("No Solution"); } return 0; }
时间: 2024-11-10 00:55:33