标签:代码 pow ima 任务 poj cap EAP navigate ESS
https://vjudge.net/problem/POJ-3041
Input
Output
Sample Input
3 4 1 1 1 3 2 2 3 2
Sample Output
2
Hint
行与行之间相互独立,一个行可以就炸掉很多列。(列的道理一样),如果替换一些字。
点与点之间相互独立,一个点就可以炸掉很多边。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<set> #include<algorithm> #include<map> #define maxn 2005 typedef long long ll; #define inf 10000009 using namespace std; int n,k; int zzz,x,y; bool can[maxn][maxn];//can[][]表示计算机i能够处理的任务 struct edge{ int to,cap,rev; //边的终点,容量,反向边 }; vector<edge>mp[maxn]; // 邻接图 bool vis[maxn]; void add_edge(int from,int to,int cap) //建图 { mp[from].push_back((edge){to,cap,mp[to].size()}); mp[to].push_back((edge){from,0,mp[from].size()-1}); //反向弧 } int dfs(int v,int t,int f) //找增广路 v,t是最终点 用了f的流量 { if(v==t)return f; vis[v]=true; for(int i=0;i<mp[v].size();i++) { edge &e=mp[v][i]; if(!vis[e.to]&&e.cap>0) { int d=dfs(e.to,t,min(f,e.cap)); //遍历所有的路径 if(d>0) { e.cap-=d; //求增加的流量 mp[e.to][e.rev].cap+=d; return d; } } } return 0; } int max_flow(int s,int t) { int flow=0; for(;;) { memset(vis,0,sizeof(vis)); //初始化 int f=dfs(s,t,inf); if(f==0)return flow; flow+=f; } } void solve() { int s=n+n+1; int t=s+1; for(int i=0;i<n;i++) { add_edge(s,i,1); } for(int i=0;i<n;i++) { add_edge(n+i,t,1); } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(can[i][j]==1) { //cout<<i<<" "<<j; add_edge(i,n+j,1); } } } cout<<max_flow(s,t)<<endl; } int main() { while(cin>>n>>k) { memset(can,0,sizeof(can)); for(int i=0;i<k;i++) { cin>>x>>y; x--; y--; can[x][y]=1; } solve(); } return 0; }
标签:代码 pow ima 任务 poj cap EAP navigate ESS
原文地址:https://www.cnblogs.com/huangzzz/p/9459196.html