题目名称是吸引你点进来的。
从前有个 n。
有一天思考熊想给这 n 个方格染上黑白两色。
第 i。
如果方格 i 的好看度。
如果方格 i 的好看度。
但是太多了黑色就不好看了。如果方格 i 就被称为奇怪的方格。
如果方格 i。
也就是说对于一个染色方案,好看度为:
i
现在给你 p,问所有染色方案中最大的好看度是多少。
输入格式
第一行一个正整数 n。
接下来 i。
保证 i。
输出格式
一个非负整数表示所有染色方案中最大的好看度。
样例一
input
10 0 1 7 3 9 2 7 4 0 9 10 5 1 0 4 2 10 2 7 9 1 5 7 2 6 3 5 3 6 2 6 6 4 1 8 1 6 1 6 0 6 5 2 2 5 0 9 3 5 1 3 0 2 5 5 6 7 1 1 2
output
55
explanation
最优染色方案为:白 黑 白 黑 白 黑 白 白 白 白
可以发现只有方格 6 为奇怪的方格。
所以好看度为:
55
限制与约定
设 p 中的最大值。
| 测试点编号 | n | max | max | max |
|---|---|---|---|---|
| 1 | 5 | 10 | 10 | 10 |
| 2 | 20 | 40 | 40 | 40 |
| 3 | 20 | 40 | 40 | 40 |
| 4 | 5000 | 10 | 200000 | 100000 |
| 5 | 5000 | 10 | 200000 | 300000 |
| 6 | 200 | 9 | 200000 | 200000 |
| 7 | 300 | 9 | 200000 | 220000 |
| 8 | 500 | 9 | 200000 | 400000 |
| 9 | 5000 | 5000 | 200000 | 150000 |
| 10 | 5000 | 9 | 200000 | 300000 |
时间限制:s
空间限制:MB
来源
VFleaKing
看WZJ这蒟蒻卡爆测评机2333333
都在这里了http://oj.cnuschool.org.cn/oj/home/educationArchiveList.htm A+B,登陆后下载
由于我现推的,和VFK论文中的写的正好相反。
暴力:
#include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #include<queue> #define rep(s,t) for(int i=s;i<=t;i++) #define ren for(int i=first[x];i!=-1;i=next[i]) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=100010; const int maxm=200010; struct Dinic { int n,m,s,t,nowd; int vis[maxn],d[maxn],cur[maxn],first[maxn],next[maxm]; struct Edge {int from,to,flow;}edges[maxm]; void init(int n) { this->n=n;m=0; fill(first+1,first+n+1,-1); } void AddEdge(int u,int v,int w) { edges[m]=(Edge){u,v,w};next[m]=first[u];first[u]=m++; edges[m]=(Edge){v,u,0};next[m]=first[v];first[v]=m++; } int BFS() { queue<int> Q; Q.push(s);d[s]=0;vis[s]=++nowd; while(!Q.empty()) { int x=Q.front();Q.pop();cur[x]=first[x]; ren { Edge& e=edges[i]; if(e.flow&&vis[e.to]!=nowd) { vis[e.to]=nowd; d[e.to]=d[x]+1; Q.push(e.to); } } } return vis[t]==nowd; } int DFS(int x,int a) { if(x==t||!a) return a; int flow=0,f; for(int& i=cur[x];i!=-1;i=next[i]) { Edge& e=edges[i]; if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(e.flow,a)))) { flow+=f;a-=f; e.flow-=f;edges[i^1].flow+=f; if(!a) break; } } return flow; } int solve(int s,int t) { this->s=s;this->t=t; int flow=0; while(BFS()) flow+=DFS(s,1e9); return flow; } }sol; int n,a[maxn],b[maxn],w[maxn],l[maxn],r[maxn],p[maxn]; void solve() { int S=2*n+1,T=2*n+2,all=0;sol.init(T); rep(1,n) sol.AddEdge(S,i,w[i]),sol.AddEdge(i,T,b[i]),all+=w[i]+b[i]; rep(1,n) { for(int j=1;j<i;j++) if(l[i]<=a[j]&&a[j]<=r[i]) sol.AddEdge(j,i+n,1e9); sol.AddEdge(i+n,i,p[i]); } printf("%d\n",all-sol.solve(S,T)); } int main() { n=read(); rep(1,n) a[i]=read(),b[i]=read(),w[i]=read(),l[i]=read(),r[i]=read(),p[i]=read(); solve(); return 0; }