bzoj1433 [ZJOI2009]假期的宿舍(最大流)
2015-12-20 16:10
423 查看
1433: [ZJOI2009]假期的宿舍
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1717 Solved: 754
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
13
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0
Sample Output
ˆ ˆHINT
对于30% 的数据满足1 ≤ n ≤ 12。对于100% 的数据满足1 ≤ n ≤ 50,1 ≤ T ≤ 20。
Source
【思路】最大流。
构图:
1
每个人建立两个点u1,u2,建立s t点。
2
如果需要床则s向u1连边,如果有床u2向t连边,如果认识u1向v2连边。
Ps:总而言之,建图的思路就是要分配已有的床给需要床的人。
【代码】
#include<cstdio> #include<cstring> #include<queue> #include<vector> #define FOR(a,b,c) for(int a=(b);a<(c);a++) using namespace std; const int maxn = 500+10; const int INF = 1e9; struct Edge{ int u,v,cap,flow; }; struct Dinic { int n,m,s,t; bool vis[maxn]; int d[maxn],cur[maxn]; vector<int> G[maxn]; vector<Edge> es; void init(int n) { this->n=n; es.clear(); for(int i=0;i<n;i++) G[i].clear(); } void AddEdge(int u,int v,int cap) { es.push_back((Edge){u,v,cap,0}); es.push_back((Edge){v,u,0,0}); m=es.size(); G[u].push_back(m-2); G[v].push_back(m-1); } bool BFS() { queue<int> q; memset(vis,0,sizeof(vis)); q.push(s); vis[s]=1; d[s]=0; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=0;i<G[u].size();i++) { Edge& e=es[G[u][i]]; int v=e.v; if(!vis[v] && e.cap>e.flow) { vis[v]=1; d[v]=d[u]+1; q.push(v); } } } return vis[t]; } int DFS(int u,int a) { if(u==t || a==0) return a; int flow=0,f; for(int& i=cur[u];i<G[u].size();i++){ Edge& e=es[G[u][i]]; int v=e.v; if( d[v]==d[u]+1 && (f=DFS(v,min(a,e.cap-e.flow)))>0 ) { e.flow+=f; es[G[u][i]^1].flow-=f; flow+=f,a-=f; if(!a) break; } } return flow; } int Maxflow(int s,int t) { this->s=s , this->t=t; int flow=0; while(BFS()) { memset(cur,0,sizeof(cur)); flow+=DFS(s,INF); } return flow; } } dc; int n,m; int f[maxn]; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); dc.init(n*2+2); int s=n*2,t=s+1; FOR(i,0,n) { scanf("%d",&f[i]); if(f[i]) dc.AddEdge(i+n,t,1); } int x,sum=0; FOR(i,0,n) { scanf("%d",&x); if((f[i]&&!x) || (!f[i])) { dc.AddEdge(s,i,1); sum++; } } FOR(i,0,n) FOR(j,0,n) { scanf("%d",&x); if(x || i==j) dc.AddEdge(i,j+n,1); } int flow=dc.Maxflow(s,t); if(flow==sum) printf("^_^\n"); else printf("T_T\n"); } return 0; }
相关文章推荐
- Week6-6Language Modelling3
- 修饰 C++ 成员函数的两种关键字总结
- 数据结构小结(七)查找
- 修饰 C++ 成员函数的两种关键字总结
- 获取相册图片,和拍照获取图片,本来很简单的东西,最后整了好久,这次写给博客,总结一下
- 杭电acm1425
- Linux C 指针练习
- OpenCV笔记(八)
- 《JAVA》中利用《动态规划》实现《背包》问题
- 基站地理定位 API (移动联通)
- 学HTML5必须要学JS吗
- FFMPEG All in One Video & Audio Converter Interface
- 轮展图
- 多点登录向单点登录的转变方案
- 关于在Mac上挂载移动硬盘实现数据备份的方法
- C语言知识整理(3):内存管理(详细版)
- 20135223何伟钦—信息安全系统设计基础第十五周期末总结
- HTML5舍弃的标签
- MySql的基本常识和crud语句大全。。。。。
- Docker