Air RaidTime Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u
Description
Input
Output
Sample Input
2 4 3 3 4 1 3 2 3 3 3 1 3 1 2 2 3
Sample Output
2 1
求最小路径覆盖(需要几条路才能无重复的走完所有点),最小路径覆盖等于顶点个数减去最大二分匹配数目。
因为如果没有任何边的话,每个点都需要一条路径,加入一条边后需要的路径减少一条,但是不能走重复的点所以就是二分匹配问题。要求最小路径覆盖就是要求最大二分匹配,代码如下:
/*************************************************************************
> File Name: c.cpp
> Author: acvcla
> QQ:
> Mail: acvcla@gmail.com
> Created Time: 2014年10月11日 星期六 08时42分28秒
************************************************************************/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<cstdlib>
#include<ctime>
#include<set>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e2 + 50;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
bool vis[maxn];
int d[maxn];
std::vector<int>G[maxn];
void init(int n){
memset(vis,0,sizeof vis);
memset(d,-1,sizeof d);
for(int i=0;i<=n;i++)G[i].clear();
}
void addadge(int u,int v){
G[u].pb(v);
}
bool match(int u){
for(int i=0;i<G[u].size();++i){
int &v=G[u][i];
if(!vis[v]){
vis[v]=1;
if(d[v]==-1||match(d[v])){
d[v]=u;
return true;
}
}
}
return false;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
int T,n,m;
cin>>T;while(T--){
while(cin>>n>>m){
init(n); int u,v;
while(m--){
cin>>u>>v;
addadge(u,v);
}
int ans=n;
for(int i=1;i<=n;i++){
memset(vis,0,sizeof v);
if(match(i))ans--;
}
cout<<ans<<endl;
}
}
return 0;
}
/*************************************************************************
> File Name: c.cpp
> Author: acvcla
> QQ
> Mail: acvcla@gmail.com
> Created Time: 2014年10月13日 星期一 22时26分17秒
************************************************************************/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<cstdlib>
#include<ctime>
#include<set>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e2 + 30;
const int INF =1e7;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
int n,m,s,t;
int d[maxn],cur[maxn];
struct Edge
{
int from,to,cap,flow;
};
std::vector<int>G[maxn];
std::vector<Edge>edges;
void init(int n){
for(int i=0;i<n;i++)G[i].clear();
edges.clear();
}
void addEdge(int u,int v)
{
edges.pb((Edge){u,v,1,0});
edges.pb((Edge){v,u,0,0});
int sz=edges.size();
G[u].pb(sz-2);
G[v].pb(sz-1);
}
int bfs(){
memset(d,0,sizeof d);
queue<int>q;
q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<G[u].size();i++){
Edge &e=edges[G[u][i]];
if(e.to==s)continue;
if(!d[e.to]&&e.cap>e.flow){
q.push(e.to);
d[e.to]=d[u]+1;
}
}
}
//cout<<t<<' '<<d[t]<<endl;
return d[t];
}
int dfs(int u,int a)
{
if(u==t||a==0)return a;
int flow=0,f=0;
for(int &i=cur[u];i<G[u].size();++i){
Edge &e=edges[G[u][i]];
if(d[e.to]==d[u]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
e.flow+=f;
edges[G[u][i]^1].flow-=f;
flow+=f;
if(a==0)break;
}
}
return flow;
}
int Dinic(){
int flow=0;
while(bfs()){
memset(cur,0,sizeof cur);
flow+=dfs(s,INF);
}
return flow;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
int T;scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
int u,v;
s=0,t=n+1;
init(t);
while(m--){
scanf("%d%d",&u,&v);
addEdge(s,u);
addEdge(u,v);
addEdge(v,t);
}
//cout<<"Dinic"<<endl;
cout<<t-Dinic()<<endl;
}
return 0;
}
原文地址:http://blog.csdn.net/acvcla/article/details/40085183