文章标题
来源:互联网 发布:core js 编辑:程序博客网 时间:2024/06/05 09:44
集训day5t3 Mike的农场
样例:
4 2 1
1 2 3 1
2 3 1 2
1 2 3
1 3 2
2 0 100 1 2
输出
108
大致就是显然的网络流,一开始以为是费用流。。。。。。遇题要先打暴力,这题暴力显然30分,然后这样建边:由于一个栅栏只能选一个,于是s向i点连一条权值为a[i]的边,i向t建一条权值为b[i],然后最小割是把失去的收益最小是显然的。。。。。然后考虑另一个限制条件,如何把两个不同的选择的损失表示出来,其实就是在两点间互相连一条权值为损失的边,画个图最小割是显然的可以最小损失吧,最后是那个集合怎么玩,新建一个点p,如果为0号,则s向p连一条权值为收益的边,p向这个限制集合内的点连一条无限大的边,1的话则p向t连权值为收益的边,点向p连无限大的边,这个最小割我是没想到的。。。。。。于是就是所有的收益-最小割就是答案。。。。。。
/************************************************************** Problem: 4177 User: tym983398371 Language: C++ Result: Accepted Time:504 ms Memory:6160 kb****************************************************************/#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include<queue>using namespace std;const int INF=1000000000;struct edge{ int to,cap,next;};edge e[200005]; int g[200005],n,m,k,cnt=0,s,t;bool vis[200005];int cur[200005],d[200005];inline void addedge(const int &from,const int &to,const int &cap){ cnt++;e[cnt].to=to;e[cnt].cap=cap;e[cnt].next=g[from];g[from]=cnt; cnt++;e[cnt].to=from;e[cnt].cap=0;e[cnt].next=g[to];g[to]=cnt; return ;}bool bfs(){ memset(vis,0,sizeof(vis)); queue<int> q; q.push(s); vis[s]=1; d[s]=0; while (!q.empty()) { int x=q.front();q.pop(); for (int i=g[x];i;i=e[i].next) { if (!vis[e[i].to]&&e[i].cap>0) { q.push(e[i].to); vis[e[i].to]=1; d[e[i].to]=d[x]+1; } } } return vis[t];}int dfs(int x,int a){ if (x==t||a==0) return a; int flow=0,f; for (int &i=cur[x];i;i=e[i].next) { if (d[e[i].to]==d[x]+1&&e[i].cap>0&&(f=dfs(e[i].to,min(a,e[i].cap)))>0) { a-=f; flow+=f; e[i].cap-=f; if (i%2==1) e[i+1].cap+=f; else e[i-1].cap-=f; if (a==0) break; } } return flow;}int main(){ scanf("%d%d%d",&n,&m,&k); s=0; long long ans=0; int x,y,z,o,t1; t=n+1; for (int i=1;i<=n;i++) { scanf("%d",&x); ans+=x; addedge(s,i,x); } for (int i=1;i<=n;i++) { scanf("%d",&x); ans+=x; addedge(i,t,x); } for (int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); addedge(x,y,z); addedge(y,x,z); } int a1,b1; o=t; for (int i=1;i<=k;i++) { scanf("%d%d%d",&t1,&a1,&b1); ans+=b1; o++; if (a1==0) { addedge(s,o,b1); for (int j=1;j<=t1;j++) { scanf("%d",&x); addedge(o,x,INF); } } else { addedge(o,t,b1); for (int j=1;j<=t1;j++) { scanf("%d",&x); addedge(x,o,INF); } } } while (bfs()) { for (int i=0;i<=o;i++) cur[i]=g[i]; //cout<<ans<<endl; ans-=dfs(s,INF); } printf("%lld\n",ans); return 0;}
0 0
- 文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题 文章标题 文章标题 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- Android端传送json字符串到Struts2端
- java的成长历程3
- 各滤镜处理效果记录,
- JavaScript高级程序设计【面向对象-属性类型】
- oauth服务端之Java版oltu
- 文章标题
- 网关 的理解
- 分享个ppt转换成pdf格式的小方法
- js中的闭包实现自增
- setTextColor属性
- jdk代理模式
- Android 使用NFC通过标签协议栈读写标签数据
- apiexample.c例子教我们如何去利用ffmpeg库中的api
- 在快要结束的时候补上吧。。。