您的位置:首页 > 理论基础 > 计算机网络

hdu 4619 Warm up 2 网络流 最小割

2013-08-03 11:03 316 查看
题意:告诉你一些骨牌,然后骨牌的位置与横竖,这样求最多保留多少无覆盖的方格。

这样的话有人用二分匹配,因为两个必定去掉一个,我用的是最小割,因为保证横着和竖着不连通即可。

#include <stdio.h>
#include <string.h>
#include <vector>
#include <iostream>
#include <queue>
#define loop(s,i,n) for(i = s;i < n;i++)
using namespace std;
const int maxn = 2050;
struct edge
{
int u,v,cap,flow;
};
vector<edge>edges;
vector<int>g[maxn],G[maxn];
void addedge(int u,int v,int cap,int flow)
{
//printf("********u %d ****v %d *****\n",u,v);
edges.push_back((edge){u,v,cap,flow});
edges.push_back((edge){v,u,0,0});
int m;
m = edges.size();
g[u].push_back(m-2);
g[v].push_back(m-1);
}
void init(int n)
{
int i;
for(i = 0;i <= n;i++)
{
g[i].clear();
}
edges.clear();
}
int vis[maxn],dis[maxn],cur[maxn];
int bfs(int s,int t,int n)
{
memset(vis,0,sizeof(vis));
queue<int>q;
q.push(s);
dis[s] = 0;
vis[s] = 1;
while(!q.empty())
{
int u,v;
u = q.front();
q.pop();
for(int i = 0;i < g[u].size();i++)
{
edge &e = edges[g[u][i]];
v = e.v;
if(!vis[v] && e.cap-e.flow > 0)
{
vis[v] = 1;
dis[v] = dis[u] +1;
q.push(v);
}
}
}
return vis[t];
}
int dfs(int u,int a,int t)
{
if(u == t || a == 0)
return a;
int v;
int flow = 0,f;
for(int& i = cur[u]; i < g[u].size();i++)
{
edge &e = edges[g[u][i]];
v = e.v;
if(dis[u]+1 == dis[v] &&(f = dfs(v,min(a,e.cap-e.flow),t)))
{
e.flow += f;
edges[g[u][i]^1].flow -= f;
flow += f;
a -= f;
if(a == 0)
break;
}
}
return flow;
}
int maxflow(int s,int t)
{
int flow = 0;
while(bfs(s,t,t))
{
memset(cur,0,sizeof(cur));
flow+=dfs(s,1000050,t);
}
return flow;
}
struct node
{
int x1,y1,x2,y2;
}px[2050],py[1050];
int lap(int a,int b)
{
if(py[a].x1 == px[b].x1 && py[a].y1 == px[b].y1)
return 1;
if(py[a].x2 == px[b].x1 && py[a].y2 == px[b].y1)
return 1;
if(py[a].x1 == px[b].x2 && py[a].y1 == px[b].y2)
return 1;
if(py[a].x2 == px[b].x2 && py[a].y2 == px[b].y2)
return 1;
return 0;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)&&(m||n))
{
int i,j;
int x,y;
init(m+n+5);
for(i = 0;i < n;i++)
{
scanf("%d %d",&x,&y);
px[i].x1 = x;
px[i].y2 =  px[i].y1 = y;
px[i].x2 = x+1;
}
for(j = 0;j < m;j++)
{
scanf("%d %d",&x,&y);
py[j].x1 = py[j].x2 = x;
py[j].y1 = py[j].y2 = y;
py[j].y2++;
}
int cnt;
cnt = 0;
loop(0,i,n)
addedge(0,i+1,1,0);
loop(0,j,m)
addedge(n+j+1,m+n+1,1,0);
loop(0,i,n)
{
loop(0,j,m)
{
if(lap(j,i))
addedge(i+1,j+n+1,1005,0);
}
}
cout<<m+n-maxflow(0,m+n+1)<<endl;
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: