xdu_1048:二分匹配模板测试
2017-03-02 20:50
260 查看
二分匹配的模板题,这里用网络流模板(见刘汝佳《算法竞赛入门经典·训练指南》P359 Dinic算法)做。
将男女生均看做网络上的节点,题中给出的每个“关系”看做一条起点为u节点,终点为v结点,容量为1的弧(因为每对“关系”只有匹配成功与失败两种情况,用1为容量即可表示)。再取超级源汇s,t,由s向每个男生结点引容量为1的弧,每个女生结点向t引容量为1的弧(每个男生或是女生最多只能匹配成功一次,容量这样设置的话,一个结点与一个异性结点匹配成功后,它与所点的源点或汇点的流量将为1,无空余容量了,也就无法再继续同第三者匹配)。最后跑最大流算法就好了。
题目链接
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;//即int的最大值
struct Edge
{
int from,to,cap,flow;
};
int n,s,t,m,A,B; // A B为本题特有
// s t为超级源汇
const int N = 1010, M = 200010;
struct Dinic
{
vector<int> G
;
bool vis
;
int d
;
int cur
;
vector<Edge> edges;
void init()
{
for(int i=0; i<n+2; i++) //注意这里的 结点下标 的范围
G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int cap)
{
edges.push_back((Edge){from,to,cap,0});
edges.push_back((Edge){to,from,0,0});
int w=edges.size();
G[from].push_back(w-2);
G[to].push_back(w-1);
}
bool bfs()
{
memset(vis,0,sizeof(vis));
queue<int>Q;
d[s] = 0;
Q.push(s);
vis[s]=1;
while (!Q.empty())
{
int x = Q.front();
Q.pop();
for (int i = 0; i<G[x].size(); i++)
{
Edge e=edges[G[x][i]];
if (!vis[e.to]&&e.cap>e.flow)
{
vis[e.to]=1;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
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<G[x].size(); i++)
{
Edge& e=edges[G[x][i]];
if (d[e.to] == d[x] + 1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
{
e.flow+=f;
edges[G[x][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())
{
memset(cur,0,sizeof(cur));
flow += dfs(s, INF);
}
// for(int i=1; i<=n; i++)
// for(int j=0; j<G[i].size(); j++)
// printf("from:%d to:%d cap:%d flow:%d\n",i,edges[G[i][j]].to,edges[G[i][j]].cap,edges[G[i][j]].flow);
return flow;
}
} g;
int main()
{
while(~scanf("%d%d",&A,&B))
{
n=A+B;
g.init();
s=n,t=n+1;
int l;
scanf("%d",&l);
while(l--)
{
int a,b;
scanf("%d%d",&a,&b);
g.AddEdge(a,b+A,1);
}
for(int i=0; i<A; i++)
g.AddEdge(s,i,1);
for(int i=0; i<B; i++)
g.AddEdge(i+A,t,1);
printf("%d\n",g.Maxflow(s,t));
}
}
将男女生均看做网络上的节点,题中给出的每个“关系”看做一条起点为u节点,终点为v结点,容量为1的弧(因为每对“关系”只有匹配成功与失败两种情况,用1为容量即可表示)。再取超级源汇s,t,由s向每个男生结点引容量为1的弧,每个女生结点向t引容量为1的弧(每个男生或是女生最多只能匹配成功一次,容量这样设置的话,一个结点与一个异性结点匹配成功后,它与所点的源点或汇点的流量将为1,无空余容量了,也就无法再继续同第三者匹配)。最后跑最大流算法就好了。
题目链接
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;//即int的最大值
struct Edge
{
int from,to,cap,flow;
};
int n,s,t,m,A,B; // A B为本题特有
// s t为超级源汇
const int N = 1010, M = 200010;
struct Dinic
{
vector<int> G
;
bool vis
;
int d
;
int cur
;
vector<Edge> edges;
void init()
{
for(int i=0; i<n+2; i++) //注意这里的 结点下标 的范围
G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int cap)
{
edges.push_back((Edge){from,to,cap,0});
edges.push_back((Edge){to,from,0,0});
int w=edges.size();
G[from].push_back(w-2);
G[to].push_back(w-1);
}
bool bfs()
{
memset(vis,0,sizeof(vis));
queue<int>Q;
d[s] = 0;
Q.push(s);
vis[s]=1;
while (!Q.empty())
{
int x = Q.front();
Q.pop();
for (int i = 0; i<G[x].size(); i++)
{
Edge e=edges[G[x][i]];
if (!vis[e.to]&&e.cap>e.flow)
{
vis[e.to]=1;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
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<G[x].size(); i++)
{
Edge& e=edges[G[x][i]];
if (d[e.to] == d[x] + 1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
{
e.flow+=f;
edges[G[x][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())
{
memset(cur,0,sizeof(cur));
flow += dfs(s, INF);
}
// for(int i=1; i<=n; i++)
// for(int j=0; j<G[i].size(); j++)
// printf("from:%d to:%d cap:%d flow:%d\n",i,edges[G[i][j]].to,edges[G[i][j]].cap,edges[G[i][j]].flow);
return flow;
}
} g;
int main()
{
while(~scanf("%d%d",&A,&B))
{
n=A+B;
g.init();
s=n,t=n+1;
int l;
scanf("%d",&l);
while(l--)
{
int a,b;
scanf("%d%d",&a,&b);
g.AddEdge(a,b+A,1);
}
for(int i=0; i<A; i++)
g.AddEdge(s,i,1);
for(int i=0; i<B; i++)
g.AddEdge(i+A,t,1);
printf("%d\n",g.Maxflow(s,t));
}
}
相关文章推荐
- xdu 1048:二分匹配模板测试
- 【二分匹配匈牙利算法模板】
- hdu2255 奔小康赚大钱(二分匹配 KM)模板 邻接矩阵
- 二分匹配模板
- csu 1552: Friends(拉宾米勒测试+二分匹配)
- poj1469 COURSES 二分匹配模板水题
- 最大流,最大权二分匹配,二分匹配算法模板
- poj 1274 The Perfect Stall 【二分匹配裸题】【练模板】
- HDU2063(二分匹配入门模板题)
- 最大权二分匹配—KM算法入门 && 模板
- poj 3692Kindergarten(二分匹配模板)
- 最大二分匹配 匈牙利算法模板&&POJ 1469 COURSES
- HDU 2444 The Accomodation of Students(最大二分匹配(匈牙利算法)+二分图判断->模板题目)
- 二分多重匹配模板
- poj 1469 COURSES(二分匹配模板)
- poj 匈牙利二分匹配 模板 poj题目
- 匈牙利算法模板 图的二分匹配 hdu 2063 过山车
- 最大流 & 二分匹配模板
- hdu 1083 Courses 二分匹配模板
- HDU 1083 Courses(二分匹配匈牙利算法模板题啊)