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