网络流24题解题报告小结
1 飞行员配对方案问题 二分图最大匹配 网络最大流
#include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FFF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 222; const int head = 0; const int end = 221; struct zz { int from; int to; int c; int id; }zx; int m,n; vector<zz>g[maxn]; int cen[maxn]; void link(int now,int to,int c,int bc) { zx.from = now; zx.to = to; zx.c = c; zx.id = g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to); zx.c = bc; zx.id = g[zx.to].size()-1; g[zx.from].pb(zx); return ; } bool bfs() { MM(cen,-1); queue<int>q; int now,to; q.push(head); cen[head]=0; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c > 0 && cen[to]==-1) { cen[to]=cen[now]+1; q.push(to); } } } return cen[end]!=-1; } int dfs(int flow = inf,int now = head) { if(now == end) { return flow; } int to,sum=0; int temp; for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0 && flow>sum && cen[to]==cen[now]+1) { temp = dfs(min(flow-sum,g[now][i].c),to); sum+=temp; g[now][i].c-=temp; g[to][g[now][i].id].c+=temp; } } if(!sum) cen[now]=-1; return sum; } int dinic() { int ans = 0; while(bfs()) { ans+=dfs(); } return ans; } int main() { int now,to; while(cin>>m>>n) { for(int i=0;i<maxn;i++) { g[i].clear(); } while(cin>>now>>to) { if(now==to && now==-1) { break; } else { link(now,to,1,0); } } for(int i=1;i<=m;i++) { link(head,i,1,0); } for(int i=m+1;i<=m+n;i++) { link(i,end,1,0); } cout<<dinic()<<endl; for(int i=1;i<=m;i++) { for(int j=0;j<g[i].size();j++) { if(g[i][j].c==0 && g[i][j].to!=head) { cout<<i<<" "<<g[i][j].to<<endl; } } } } return 0; }
2
太空飞行计划问题 最大权闭合图
网络最小割
#include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FFF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 222; const int add = 111; const int head = 0; const int end = 221; struct zz { int from; int to; int c; int id; }zx; vector<zz>g[maxn]; int cen[maxn]; int tot; vector<int>v; int m,n; bool vis[maxn]; void link(int now,int to,int c,int bc) { zx.from = now; zx.to = to; zx.c = c; zx.id = g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to); zx.c = bc; zx.id = g[zx.to].size()-1; g[zx.from].pb(zx); return ; } bool bfs() { MM(cen,-1); queue<int>q; cen[head] = 0; q.push(head); int now,to; while(!q.empty()) { now=q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c > 0 && cen[to]==-1) { cen[to] = cen[now]+1; q.push(to); } } } return cen[end]!=-1; } int dfs(int flow = inf,int now = head) { if(now == end) return flow; int to,temp,sum=0; for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(flow>sum && g[now][i].c>0 && cen[to]==cen[now]+1) { temp = dfs(min(g[now][i].c,flow-sum),to); sum += temp; g[now][i].c-=temp; g[to][g[now][i].id].c+=temp; } } if(!sum) cen[now]=-1; return sum; } int dinic() { int ans = 0; while(bfs()) { ans+=dfs(); } return tot-ans; } void find() { bfs(); MM(vis,false); for(int now=0;now<maxn;now++) { if(cen[now]==-1) continue; for(int i=0;i<g[now].size();i++) { int to = g[now][i].to; if(cen[to]==-1) { if(now == head) { vis[to]=true; } else if(to == end) { v.pb(now-add); } } } } return ; } int main() { while(cin>>m>>n) { tot=0; for(int i=0;i<maxn;i++) { g[i].clear(); } int s,to; for(int now=1;now<=m;now++) { cin>>s; tot+=s; link(head,now,s,0); while(cin.peek()!='\n') { cin>>to; to+=add; link(now,to,inf,0); } } for(int now=1;now<=n;now++) { cin>>s; to = now+add; link(to,end,s,0); } int ans = dinic(); v.clear(); find(); int ti; for(int i=1;i<=m;i++) { if(!vis[i]) { ti = i; cout<<i; break; } } for(int i=ti+1;i<=m;i++) { if(!vis[i]) { cout<<" "<<i; } } cout<<endl; if(!v.empty()) cout<<v[0]; for(int i=1;i<v.size();i++) { cout<<" "<<v[i]; } cout<<endl; cout<<ans<<endl; } return 0; }3 最小路径覆盖问题 有向无环图最小路径覆盖 网络最大流
#include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FFF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 555; const int add = 222; const int head = 0; const int end = 551; struct zz { int from; int to; int c; int id; }zx; vector<zz>g[maxn]; int cen[maxn]; int n,m; bool vis[maxn]; int go[maxn]; void link(int now,int to,int c,int bc) { zx.from = now; zx.to = to; zx.c = c; zx.id = g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to); zx.c = bc; zx.id = g[zx.to].size()-1; g[zx.from].pb(zx); return ; } bool bfs() { queue<int>q; MM(cen,-1); cen[head]=0; q.push(head); int now,to; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(cen[to]==-1 && g[now][i].c>0) { cen[to]=cen[now]+1; q.push(to); } } } return cen[end]!=-1; } int dfs(int flow=inf,int now=head) { if(now == end) return flow; int to,temp,sum=0; for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0 && flow>sum && cen[to]==cen[now]+1) { temp = dfs(min(flow-sum,g[now][i].c),to); sum+=temp; g[now][i].c-=temp; g[to][g[now][i].id].c+=temp; } } if(!sum) cen[now] = -1; return sum; } int dinic() { int ans = 0; while(bfs()) { ans+=dfs(); } return ans; } int main() { while(cin>>n>>m) { for(int i=0;i<maxn;i++) { g[i].clear(); } int now,to; for(int i=1;i<=m;i++) { cin>>now>>to; link(now,to+add,1,0); } for(int i=1;i<=n;i++) { link(head,i,1,0); } for(int i=1+add;i<=n+add;i++) { link(i,end,1,0); } int ans = dinic(); ans = n-ans; MM(vis,false); MM(go,0); for(int i=1;i<=n;i++) { for(int j=0;j<g[i].size();j++) { to = g[i][j].to; if(g[i][j].c == 0 && to!=head) { go[i]=to-add; vis[to-add]=true; } } } for(int i=1;i<=n;i++) { if(!vis[i]) { now = i; cout<<now; while(go[now]) { cout<<" "<<go[now]; now = go[now]; } cout<<endl; } } cout<<ans<<endl; } return 0; }4 魔术球问题 有向无环图最小路径覆盖 网络最大流
#include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FFF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 4555; const int add = 2222; const int end = 4554; const int head = 0; struct zz { int from; int to; int c; int id; }zx; vector<zz>g[maxn]; int cen[maxn]; int n; bool vis[maxn]; int go[maxn]; bool sq[10001]; void link(int now,int to,int c,int bc) { zx.from = now; zx.to = to; zx.c = c; zx.id = g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to); zx.c = bc; zx.id = g[zx.to].size()-1; g[zx.from].pb(zx); return ; } bool bfs() { queue<int>q; MM(cen,-1); cen[head]=0; q.push(head); int now,to; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(cen[to]==-1 && g[now][i].c>0) { cen[to]=cen[now]+1; q.push(to); } } } return cen[end]!=-1; } int dfs(int flow=inf,int now=head) { if(now == end) return flow; int to,temp,sum=0; for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0 && flow>sum && cen[to]==cen[now]+1) { temp = dfs(min(flow-sum,g[now][i].c),to); sum+=temp; g[now][i].c-=temp; g[to][g[now][i].id].c+=temp; } } if(!sum) cen[now] = -1; return sum; } int dinic() { int ans = 0; while(bfs()) { ans+=dfs(); } return ans; } void extend(int x) { for(int i=1;i<x;i++) { if(sq[i+x]) { link(i,x+add,1,0); } } link(head,x,1,0); link(x+add,end,1,0); return ; } void start() { for(int i=0;i<maxn;i++) { g[i].clear(); } int flow = 0; int temp = 0; int tot; for(int i=1;temp<=n;i++) { extend(i); flow += dinic(); temp = i-flow; tot=i; } tot--; for(int i=0;i<maxn;i++) { g[i].clear(); } for(int i=1;i<=tot;i++) { extend(i); } int ans = dinic(); MM(vis,false); MM(go,0); int to; for(int i=1;i<=tot;i++) { for(int j=0;j<g[i].size();j++) { to = g[i][j].to; if(to!=head && g[i][j].c == 0) { go[i]=to-add; vis[to-add] = true; } } } int now; cout<<tot<<endl; for(int i=1;i<=tot;i++) { if(!vis[i]) { cout<<i; now = i; while(go[now]) { cout<<" "<<go[now]; now = go[now]; } cout<<endl; } } return ; } int main() { MM(sq,false); for(int i=1;i<=100;i++) { sq[i*i]=true; } cin>>n; start(); // system("pause"); return 0; }5 圆桌问题 二分图多重匹配 网络最大流
6 最长递增子序列问题 最多不相交路径 网络最大流
7 试题库问题 二分图多重匹配 网络最大流
8 机器人路径规划问题 (未解决) 最小费用最大流 byvoid都没做
9 方格取数问题 二分图点权最大独立集 网络最小割
10
餐巾计划问题 线性规划网络优化
最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 2022; const int add = 1001; const int head = 0; const int end = 2021; struct zz { int from; int to; int c; int cost; int id; }zx; vector<zz>g[maxn]; int n,p,m,f,nd,s; int r[maxn]; int way[maxn]; int bid[maxn]; bool inq[maxn]; void link(int now,int to,int c,int cost,int bc=0) { zx.from = now;zx.to=to;zx.c=c;zx.cost=cost; zx.id = g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to); zx.c=bc;zx.cost=-cost; zx.id = g[zx.to].size()-1; g[zx.from].pb(zx); return ; } bool spfa() { for(int i=0;i<maxn;i++) way[i]=inf; way[head]=0; queue<int>q; MM(inq,false); inq[head]=true; q.push(head); int now,to,temp; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0) { temp = g[now][i].cost+way[now]; if(temp<way[to]) { bid[to] = g[now][i].id; way[to] = temp; if(!inq[to]) { inq[to]=true; q.push(to); } } } } inq[now]=false; } return way[end]!=inf; } pair<int,int> dfs(int flow = inf,int to = end) { if(to == head) return make_pair(flow,0); int now=g[to][bid[to]].to; int id = g[to][bid[to]].id; pair<int,int>temp=dfs(min(flow,g[now][id].c),now); g[now][id].c-=temp.X; g[to][bid[to]].c+=temp.X; temp.Y+=temp.X*g[now][id].cost; return temp; } int gao() { int ans=0; while(spfa()) { ans+=dfs().Y; } return ans; } int main() { while(cin>>n>>p>>m>>f>>nd>>s) { for(int i=0;i<maxn;i++) { g[i].clear(); } for(int i=1;i<=n;i++) { SS(r[i]); } for(int i=1;i<=n;i++) { link(head,i,r[i],0); link(head,i+add,inf,p); link(i+add,end,r[i],0); } int now,to; for(int i=1;i<=n-1;i++) { link(i,i+1,inf,0); // link(i+add,i+add+1,inf,0); } for(int i=1;i<=n;i++) { now=i;to=i+add+m; if(to<=add+n) link(now,to,inf,f); now=i;to=i+add+nd; if(to<=add+n) link(now,to,inf,s); } cout<<gao()<<endl; } return 0; }11 航空路线问题 最长不相交路径 最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 2111; const int add = 1001; const int head = 0; const int end = 2110; struct zz { int from; int to; int c; int cost; int id; }zx; string s[maxn]; map<string,int>ms; int n,m; vector<zz>g[maxn]; vector<int>v; vector<int>v2; int way[maxn]; bool inq[maxn]; int bid[maxn]; void link(int now,int to,int c,int cost,int bc=0) { zx.from=now;zx.to=to;zx.c=c;zx.cost=cost; zx.id=g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to); zx.c=bc;zx.cost=-cost; zx.id=g[zx.to].size()-1; g[zx.from].pb(zx); return ; } bool spfa() { for(int i=0;i<maxn;i++) { way[i]=-inf; } way[head]=0; deque<int>q; MM(inq,false); inq[head]=true; q.pb(head); int now,to,temp; while(!q.empty()) { now = q.front(); q.pop_front(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0) { temp = g[now][i].cost+way[now]; if(temp>way[to]) { bid[to] = g[now][i].id; way[to] = temp; if(!inq[to]) { inq[to]=true; // if(q.empty() || way[to]<way[q.front()]) q.pf(to); //最小费用流 // else if(q.empty() || way[to]>way[q.front()]) q.pf(to); //最大费用流 else q.pb(to); } } } } inq[now]=false; } return way[end]!=-inf; } pair<int,int> dfs(int flow = inf,int to = end) { if(to == head) return make_pair(flow,0); int now=g[to][bid[to]].to; int id = g[to][bid[to]].id; pair<int,int>temp=dfs(min(flow,g[now][id].c),now); g[now][id].c-=temp.X; g[to][bid[to]].c+=temp.X; temp.Y+=temp.X*g[now][id].cost; return temp; } bool gao() { pair<int,int>ans,temp; ans.X=ans.Y=0; while(spfa()) { temp = dfs(); ans.X+=temp.X; ans.Y+=temp.Y; } if(ans.X==2) { int now = 1; int to; v.clear(); v2.clear(); v.pb(now); while(now!=n) { now+=add; for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c<2 && to!=now-add) { g[now][i].c++; v.pb(to); now = to; break; } } } now = 1; v2.pb(now); while(now!=n) { now+=add; for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c<2 && to!=now-add) { g[now][i].c++; v2.pb(to); now = to; break; } } } v2.pop_back(); cout<<ans.Y<<endl; return true; } return false; } int main() { while(cin>>n>>m) { ms.clear(); for(int i=0;i<maxn;i++) { g[i].clear(); } for(int i=1;i<=n;i++) { cin>>s[i]; } for(int i=1;i<=n;i++) { link(i,i+add,1,1); } link(1,1+add,1,0); link(n,n+add,1,0); link(head,1,2,0); link(n+add,end,2,0); for(int i=1;i<=n;i++) { ms[s[i]]=i; } string sa,sb; int now,to; for(int i=1;i<=m;i++) { cin>>sa>>sb; now = ms[sa]; to = ms[sb]; if(now>to) swap(now,to); link(now+add,to,2,0); } if(gao()) { for(int i=0;i<v.size();i++) { cout<<s[v[i]]<<endl; } int size = v2.size()-1; for(int i=size;i>=0;i--) { cout<<s[v2[i]]<<endl; } } else { cout<<"No Solution!"<<endl; } } return 0; }12 软件补丁问题 最小转移代价 最短路径
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 1<<20; const int maxz = 111; struct zz { int from; int to; int cost; }zx; int dp[maxn]; int n,m; int b[maxz]; int b2[maxz]; int f[maxz]; int f2[maxz]; int t[maxz]; vector<zz>g[maxn]; inline void link(int& now,int& to,int& cost) { zx.from = now; zx.to = to; zx.cost = cost; g[zx.from].pb(zx); return ; } int find(string &s) { int re=0; int temp; for(int i=0;i<s.length();i++) { if(s[i]=='+') { temp = 1<<i; re+=temp; } } return re; } int find2(string &s) { int re=0; int temp; for(int i=0;i<s.length();i++) { if(s[i]=='-') { temp = 1<<i; re+= temp; } } return re; } bool inq[maxn]; int spfa() { queue<int>q; MM(inq,false); for(int i=0;i<(1<<n);i++) { dp[i]=inf; } dp[0]=0; inq[0] = true; q.push(0); int now,to,temp; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; temp = dp[now]+g[now][i].cost; if(temp<dp[to]) { dp[to] =temp; if(!inq[to]) { inq[to]=true; q.push(to); } } } inq[now]=false; } return dp[(1<<n)-1]; } int main() { string sa,sb; while(cin>>n>>m) { for(int i=0;i<(1<<n);i++) { g[i].clear(); } for(int i=1;i<=m;i++) { cin>>t[i]>>sa>>sb; b[i] = find(sa); b2[i] = find2(sa); f[i] = find2(sb); f2[i] = find(sb); } int now,to,temp; for(int i=0;i<(1<<n);i++) { for(int j=1;j<=m;j++) { if(i & b[j]) continue; now = ~i; if(now & b2[j]) continue; now = i; to = now | f[j]; temp = ~f2[j]; to &= temp; link(now,to,t[j]); } } int ans = spfa(); if(ans!=inf) { cout<<ans<<endl; } else { cout<<"0"<<endl; } } return 0; }13 星际转移问题 网络判定 网络最大流
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 5111; const int maxm = 22; const int end = 5110; const int head = 0; struct zz { int from; int to; int c; int id; }zx; int n,m,k; vector<zz>g[maxn]; int c[maxm]; vector<int>v[maxm]; int p[maxm]; int back[maxn]; bool inq[maxn]; int f[maxm]; void link(int now,int to,int c,int bc=0) { zx.from = now;zx.to=to;zx.c=c;zx.id=g[zx.to].size();g[zx.from].pb(zx); swap(zx.from,zx.to);zx.id=g[zx.to].size()-1;zx.c=bc;g[zx.from].pb(zx); return ; } bool bfs() { MM(inq,false); queue<int>q; back[head]=back[end]=-1; inq[head]=true; q.push(head); int now,to,temp; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0) { if(!inq[to]) { inq[to]=true; back[to]=g[now][i].id; q.push(to); } } } if(inq[end]) break; } return back[end]!=-1; } int dfs(int flow = inf,int to = end) { if(to == head) return flow; int now = g[to][back[to]].to; int id = g[to][back[to]].id; int re = dfs(min(flow,g[now][id].c),now); g[now][id].c-=re; g[to][back[to]].c+=re; return re; } int ek() { int re = 0; while(bfs()) { re+=dfs(); } return re; } int num(int day,int x) { return (n+1)*day + x; } void add(int day) { int now,to,temp; for(int i=1;i<=m;i++) { temp = day%p[i]; if(!temp) now = v[i].back(); else now = v[i][temp-1]; to = v[i][temp]; if(now!=-1) { if(to == -1) { link(num(day-1,now),end,c[i]); } else { link(num(day-1,now),num(day,to),c[i]); } } } for(int i=0;i<=n;i++) { link(num(day-1,i),num(day,i),inf); } return ; } int start() { int flow=0; int ans; for(ans=1;flow<k;ans++) { add(ans); flow += ek(); } return ans-1; } int find(int x) { if(x!=f[x]) return f[x]=find(f[x]); return x; } int main() { while(cin>>n>>m>>k) { for(int i=0;i<maxm;i++) f[i]=i; for(int i=0;i<maxn;i++) g[i].clear(); for(int i=0;i<maxm;i++) v[i].clear(); for(int i=1;i<=m;i++) { cin>>c[i]>>p[i]; int temp; int pre,t2; for(int x=1;x<=p[i];x++) { cin>>temp; v[i].pb(temp); if(temp==-1) { t2 = n+1; } else t2 = temp; if(x>=2) { f[find(pre)]=find(t2); } pre = t2; } f[find(pre)]=find(v[i][0]); } if(find(0)!=find(n+1)) { cout<<"0"<<endl; } else { cout<<start()<<endl; } } return 0; }
14 孤岛营救问题 分层图最短路径 最短路径
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxs = 1<<11; const int maxn = 222; const int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; struct zz { int x; int s; }zx; int head,end; int dp[maxn][maxs]; int f[maxn]; int go[maxn][4]; int n,m,p,k,s; int num(int x,int y) { return (x-1)*m+y; } int getx(int temp) { return (temp-1)/m+1; } int gety(int temp) { return (temp-1)%m+1; } bool yes(int x,int y) { if(x>=1 && x<=n && y>=1 && y<= m) return true; return false; } int fd(int dx,int dy) { if(dx==-1) { return 0; } if(dx==1) { return 1; } if(dy==-1) { return 2; } if(dy==1) { return 3; } assert(false); } bool inq[maxn][maxs]; int spfa() { zz now,to; queue<zz>q; MM(inq,false); now.x = num(1,1); now.s = f[num(1,1)]; inq[now.x][now.s]=true; dp[now.x][now.s]=0; q.push(now); int x,y; int temp; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<4;i++) { if(go[now.x][i]!=-1 && !(~now.s & go[now.x][i]) ) { x=getx(now.x)+dir[i][0]; y=gety(now.x)+dir[i][1]; if(yes(x,y)) { to.x = num(x,y); to.s = now.s | f[to.x]; temp = dp[now.x][now.s]+1; if(dp[to.x][to.s]>temp) { dp[to.x][to.s] = temp; if(!inq[to.x][to.s]) { inq[to.x][to.s]=true; q.push(to); } } } } } inq[now.x][now.s]=false; } int ans=inf; for(int i=0;i<(1<<p);i++) { ans=min(ans,dp[num(n,m)][i]); } if(ans == inf) return -1; return ans; } int main() { while(cin>>n>>m>>p) { for(int i=0;i<maxn;i++) { for(int j=0;j<(1<<p);j++) { dp[i][j]=inf; } } MM(go,0); MM(f,0); cin>>k; int x,y,x2,y2,temp; for(int i=1;i<=k;i++) { cin>>x>>y>>x2>>y2>>temp; if(temp==0) { go[num(x,y)][fd(x2-x,y2-y)]=-1; go[num(x2,y2)][fd(x-x2,y-y2)]=-1; } else { temp--; go[num(x,y)][fd(x2-x,y2-y)]=(1<<temp); go[num(x2,y2)][fd(x-x2,y-y2)]=(1<<temp); } } cin>>s; for(int i=1;i<=s;i++) { cin>>x>>y>>temp; temp--; f[num(x,y)]|=(1<<temp); } cout<<spfa()<<endl; } return 0; }
15 汽车加油行驶问题 分层图最短路径 最短路径
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; const int maxn = 111; struct zz { int x; int y; int s; }zx; int n,k,a,b,c; int ary[maxn][maxn]; int dp[maxn][maxn][11]; bool inq[maxn][maxn][11]; bool yes(int x,int y) { if(x>=1 && x<=n && y>=1 && y<=n) return true; return false; } int spfa() { queue<zz>q; zx.x = zx.y =1; zx.s = k; inq[zx.x][zx.y][zx.s]=true; dp[zx.x][zx.y][zx.s]=0; q.push(zx); zz now,to; int temp,add,ts; while(!q.empty()) { now = q.front(); q.pop(); if(now.s == 0) { ts=k; add = a+c; } else { ts=now.s; add=0; } for(int i=0;i<2;i++) { to.x = now.x + dir[i][0]; to.y = now.y + dir[i][1]; to.s = ts - 1; if(yes(to.x,to.y)) { temp = dp[now.x][now.y][now.s]+add; if(ary[to.x][to.y]) { temp+=a; to.s = k; } if(temp<dp[to.x][to.y][to.s]) { dp[to.x][to.y][to.s] = temp; if(!inq[to.x][to.y][to.s]) { inq[to.x][to.y][to.s] = true; q.push(to); } } } } add+=b; for(int i=2;i<4;i++) { to.x = now.x + dir[i][0]; to.y = now.y + dir[i][1]; to.s = ts - 1; if(yes(to.x,to.y)) { temp = dp[now.x][now.y][now.s]+add; if(ary[to.x][to.y]) { temp+=a; to.s = k; } if(temp<dp[to.x][to.y][to.s]) { dp[to.x][to.y][to.s] = temp; if(!inq[to.x][to.y][to.s]) { inq[to.x][to.y][to.s] = true; q.push(to); } } } } inq[now.x][now.y][now.s]=false; } int re=inf; for(int i=0;i<=k;i++) { re=min(re,dp[n][n][i]); } if(re==inf) return -1; return re; } int start() { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { for(int x=0;x<=k;x++) { dp[i][j][x]=inf; inq[i][j][x]=false; } } } return spfa(); } int main() { while(cin>>n>>k>>a>>b>>c) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cin>>ary[i][j]; } } cout<<start()<<endl; } return 0; }16 数字梯形问题 最大权不相交路径 最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 822; const int add = 411; const int head = 0; const int end = 821; struct zz { int from; int to; int c; int cost; int id; }zx; int a[22][22]; int n,m; vector<zz>g[maxn]; int way[maxn]; int back[maxn]; void link(int now,int to,int c,int cost,int bc = 0) { zx.from = now; zx.to = to; zx.c = c; zx.cost = cost; zx.id = g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to); zx.c = bc; zx.cost = -cost; zx.id = g[zx.to].size()-1; g[zx.from].pb(zx); return ; } int num(int x,int y) { return (x-1)*20+y; } void build(int ax=1,int bx=1) { for(int i=0;i<maxn;i++) { g[i].clear(); } int now,to; for(int i=1;i<=m;i++) { now = num(1,i); link(head,now,1,0); } for(int i=1;i<=n;i++) { for(int j=1;j<i+m;j++) { link(num(i,j),num(i,j)+add,ax,a[i][j]); } } for(int i=1;i<n;i++) { for(int j=1;j<i+m;j++) { link(num(i,j)+add,num(i+1,j),bx,0); link(num(i,j)+add,num(i+1,j+1),bx,0); } } for(int i=1;i<n+m;i++) { link(num(n,i)+add,end,inf,0); } return ; } bool inq[maxn]; int spfa() { MM(way,-1); MM(back,-1); deque<int>q; q.clear(); MM(inq,false); inq[head] = true; q.push_back(head); way[head] = 0; int now,to,temp; while(!q.empty()) { now = q.front(); q.pop_front(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0) { temp = g[now][i].cost+way[now]; if(temp>way[to]) { back[to]=g[now][i].id; way[to]=temp; if(!inq[to]) { inq[to]=true; if(q.empty() || temp>way[q.front()]) q.pf(to); else q.pb(to); } } } } inq[now]=false; } return way[end]!=-1; } pair<int,int> dfs(int flow=inf,int to=end) { if(to == head) return make_pair(flow,0); int now = g[to][back[to]].to; int id = g[to][back[to]].id; pair<int,int>temp = dfs(min(g[now][id].c,flow),now); g[now][id].c-=temp.X; g[to][back[to]].c+=temp.X; temp.Y+=temp.X*g[now][id].cost; return temp; } int ek() { int re=0; while(spfa()) { re+=dfs().Y; } return re; } void start() { build(1,1); cout<<ek()<<endl; build(inf,1); cout<<ek()<<endl; build(inf,inf); cout<<ek()<<endl; return ; } int main() { while(cin>>m>>n) { for(int i=1;i<=n;i++) { for(int j=1;j<i+m;j++) { cin>>a[i][j]; } } start(); } return 0; }
17 运输问题 网络费用流量 最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 222; const int head = 0; const int end = 221; struct zz { int from; int to; int c; int cost; int id; }zx; vector<zz>g[maxn]; int m,n; int a[maxn]; bool inq[maxn]; int way[maxn]; int back[maxn]; int f[maxn][maxn]; void link(int now,int to,int c,int cost,int bc=0) { zx.from = now; zx.to=to; zx.c=c; zx.cost=cost; zx.id=g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to); zx.c=bc; zx.cost=-cost; zx.id=g[zx.to].size()-1; g[zx.from].pb(zx); return ; } bool spfa(bool x) { if(x) { for(int i=0;i<maxn;i++) { way[i]=-inf; } } else { for(int i=0;i<maxn;i++) { way[i]=inf; } } MM(back,-1); queue<int>q; MM(inq,false); inq[head]=true; way[head]=0; q.push(head); int now,to,temp; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0) { temp = g[now][i].cost + way[now]; if(x) { if(temp>way[to]) { back[to] = g[now][i].id; way[to]=temp; if(!inq[to]) { inq[to]=true; q.push(to); } } } else { if(temp<way[to]) { back[to]=g[now][i].id; way[to]=temp; if(!inq[to]) { inq[to]=true; q.push(to); } } } } } inq[now]=false; } if(x) { return way[end]!=-inf; } else { return way[end]!=inf; } } int dfs(int flow=inf,int to=end) { if(to == head) return flow; int now = g[to][back[to]].to; int id = g[to][back[to]].id; int re = dfs(min(flow,g[now][id].c),now); g[now][id].c-=re; g[to][back[to]].c+=re; return re; } int ek(bool x) { int ans = 0; while(spfa(x)) { ans+=dfs()*way[end]; } return ans; } void build() { for(int i=0;i<maxn;i++) { g[i].clear(); } for(int i=1;i<=m;i++) { link(head,i,a[i],0); } for(int i=m+1;i<=m+n;i++) { link(i,end,a[i],0); } int cost; for(int i=1;i<=m;i++) { for(int j=m+1;j<=m+n;j++) { link(i,j,inf,f[i][j]); } } return ; } int main() { while(cin>>m>>n) { for(int i=1;i<=m;i++) { cin>>a[i]; } for(int i=1+m;i<=n+m;i++) { cin>>a[i]; } for(int i=1;i<=m;i++) { for(int j=m+1;j<=m+n;j++) { cin>>f[i][j]; } } build(); cout<<ek(false)<<endl; build(); cout<<ek(true)<<endl; } return 0; }
18 分配问题 二分图最佳匹配 最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 222; const int head = 0; const int end = 221; struct zz { int from; int to; int c; int cost; int id; }zx; int n; vector<zz>g[maxn]; int cx[maxn][maxn]; void link(int now,int to,int c,int cost,int bc=0) { zx.from = now,zx.to =to,zx.c = c,zx.cost=cost; zx.id = g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to),zx.c = bc,zx.cost = -cost; zx.id = g[zx.to].size()-1; g[zx.from].pb(zx); return ; } int way[maxn]; bool inq[maxn]; int back[maxn]; bool spfa(bool x) { if(x) for(int i=0;i<maxn;i++) way[i] = inf; else for(int i=0;i<maxn;i++) way[i] = -inf; queue<int>q; inq[head]=true; q.push(head); way[head]=0; int now,to,temp; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0) { temp = way[now]+g[now][i].cost; if(x) { if(temp<way[to]) { way[to]=temp; back[to]=g[now][i].id; if(!inq[to]) { inq[to]=true; q.push(to); } } } else { if(temp>way[to]) { way[to]=temp; back[to]=g[now][i].id; if(!inq[to]) { inq[to]=true; q.push(to); } } } } } inq[now]=false; } if(x) return way[end]!=inf; else return way[end]!=-inf; } int dfs(int flow=inf,int to=end) { if(to==head) return flow; int now = g[to][back[to]].to; int id = g[to][back[to]].id; int temp = dfs(min(flow,g[now][id].c),now); g[now][id].c-=temp; g[to][back[to]].c+=temp; return temp; } int ek(bool x) { int ans=0; while(spfa(x)) { ans+=dfs()*way[end]; } return ans; } void build() { for(int i=0;i<maxn;i++) { g[i].clear(); } for(int i=1;i<=n;i++) { for(int j=n+1;j<=n+n;j++) { link(i,j,1,cx[i][j]); } } for(int i=1;i<=n;i++) { link(head,i,1,0); } for(int i=n+1;i<=n+n;i++) { link(i,end,1,0); } return ; } int main() { while(cin>>n) { for(int i=1;i<=n;i++) { for(int j=n+1;j<=n+n;j++) { cin>>cx[i][j]; } } build(); cout<<ek(true)<<endl; build(); cout<<ek(false)<<endl; } return 0; }19 负载平衡问题 最小代价供求 最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 222; const int head = 0; const int end = 221; struct zz { int from; int to; int c; int cost; int id; }zx; vector<zz>g[maxn]; int n; int dis(int x,int y) { if(x>y) swap(x,y); int re = y-x; re = min(n-re,re); return re; } int way[maxn]; bool inq[maxn]; int back[maxn]; void link(int now,int to,int c,int cost,int bc=0) { zx.from=now,zx.to=to,zx.c=c,zx.cost=cost; zx.id=g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to);zx.c=bc,zx.cost=-cost; zx.id=g[zx.to].size()-1; g[zx.from].pb(zx); return ; } bool spfa() { MM(inq,false); MM(back,-1); for(int i=0;i<maxn;i++) way[i]=inf; queue<int>q; way[head]=0; inq[head]=true; q.push(head); int now,to,temp; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0) { temp = way[now]+g[now][i].cost; if(temp<way[to]) { way[to]=temp; back[to]=g[now][i].id; if(!inq[to]) { inq[to]=true; q.push(to); } } } } inq[now]=false; } return way[end]!=inf; } int dfs(int flow=inf,int to=end) { if(to==head) return flow; int now = g[to][back[to]].to; int id = g[to][back[to]].id; int temp = dfs(min(flow,g[now][id].c),now); g[now][id].c-=temp; g[to][back[to]].c+=temp; return temp; } int ek() { int ans=0; while(spfa()) { ans+=dfs()*way[end]; } return ans; } int main() { int temp,sum=0; while(cin>>n) { for(int i=0;i<maxn;i++) g[i].clear(); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { link(i,j+n,inf,dis(i,j)); } } for(int i=1;i<=n;i++) { cin>>temp; sum+=temp; link(head,i,temp,0); } sum/=n; for(int i=n+1;i<=n+n;i++) { link(i,end,sum,0); } cout<<ek()<<endl; } return 0; }
20 深海机器人问题 线性规划网络优化 最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 333; const int head = 0; const int end = 332; struct zz { int from; int to; int c; int cost; int id; }zx; vector<zz>g[maxn]; int ax,bx,n,m; int num(int x,int y) { return (x-1)*(m+1)+y; } int way[maxn]; bool inq[maxn]; int back[maxn]; void link(int now,int to,int c,int cost,int bc=0) { zx.from=now;zx.to=to;zx.c=c;zx.cost=cost; zx.id = g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to);zx.c=bc;zx.cost=-cost; zx.id = g[zx.to].size()-1; g[zx.from].pb(zx); return ; } bool spfa() { MM(inq,false); MM(back,-1); for(int i=0;i<maxn;i++) way[i]=-inf; queue<int>q; q.push(head); inq[head]=true; way[head]=0; int now,to,temp; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0) { temp = way[now]+g[now][i].cost; if(temp>way[to]) { way[to]=temp; back[to]=g[now][i].id; if(!inq[to]) { inq[to]=true; q.push(to); } } } } inq[now]=false; } return way[end]!=-inf; } int dfs(int flow=inf,int to=end) { if(to==head) return flow; int now=g[to][back[to]].to; int id =g[to][back[to]].id; int temp = dfs(min(flow,g[now][id].c),now); g[now][id].c-=temp; g[to][back[to]].c+=temp; return temp; } int ek() { int ans=0; while(spfa()) { ans+=dfs()*way[end]; } return ans; } int main() { while(cin>>ax>>bx) { cin>>n>>m; int temp; for(int i=1;i<=n+1;i++) { for(int j=1;j<=m;j++) { cin>>temp; link(num(i,j),num(i,j+1),1,temp); link(num(i,j),num(i,j+1),inf,0); } } for(int i=1;i<=m+1;i++) { for(int j=1;j<=n;j++) { cin>>temp; link(num(j,i),num(j+1,i),1,temp); link(num(j,i),num(j+1,i),inf,0); } } int x,y; for(int i=1;i<=ax;i++) { cin>>temp>>x>>y; x++;y++; link(head,num(x,y),temp,0); } for(int i=1;i<=bx;i++) { cin>>temp>>x>>y; x++;y++; link(num(x,y),end,temp,0); } cout<<ek()<<endl; } return 0; }
21 最长k可重区间集问题 最大权不相交路径 最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 #define i64 __int64 #define out64 "%I64d\n" #define in64 "%I64d" #else #define i64 long long #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define pf push_front #define X first #define Y second #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define MC(a,b) memcpy(a,b,sizeof(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 4111; const int head = 0; const int add = 2011; const int end = 4110; struct zz { int from; int to; int c; int cost; int id; }zx; int n,k; int x[maxn]; int y[maxn]; map<int,int>mx; vector<int>v,vx; vector<zz>g[maxn]; void link(int now,int to,int c,int cost,int bc=0) { zx.from=now;zx.to=to;zx.c=c;zx.cost=cost; zx.id=g[zx.to].size(); g[zx.from].pb(zx); swap(zx.from,zx.to);zx.c=bc;zx.cost=-cost; zx.id=g[zx.to].size()-1; g[zx.from].pb(zx); return ; } int way[maxn]; bool inq[maxn]; int back[maxn]; bool spfa() { for(int i=0;i<maxn;i++) way[i]=-inf; MM(inq,false); MM(back,-1); queue<int>q; inq[head]=true; way[head]=0; q.push(head); int now,to,temp; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(g[now][i].c>0) { temp = way[now]+g[now][i].cost; if(temp>way[to]) { way[to] = temp; back[to]=g[now][i].id; if(!inq[to]) { inq[to]=true; q.push(to); } } } } inq[now]=false; } return way[end]!=-inf; } int dfs(int flow=inf,int to=end) { if(to==head) { return flow; } int now = g[to][back[to]].to; int id = g[to][back[to]].id; int temp = dfs(min(flow,g[now][id].c),now); g[now][id].c -= temp; g[to][back[to]].c += temp; return temp; } int ek() { int ans = 0; while(spfa()) { ans+=dfs()*way[end]; } return ans; } int main() { while(cin>>n>>k) { v.clear(); vx.clear(); mx.clear(); for(int i=1;i<=n;i++) { cin>>x[i]>>y[i]; vx.pb(x[i]); vx.pb(y[i]); } sort(vx.begin(),vx.end()); int temp=inf; v.pb(-1); for(int i=0;i<vx.size();i++) { if(vx[i]!=temp) { temp = vx[i]; v.pb(vx[i]); v.pb(-1); } } for(int i=1;i<v.size();i++) { mx[v[i]]=i; } for(int i=0;i<maxn;i++) { g[i].clear(); } int cnt = v.size()-1; for(int i=1;i<=cnt;i++) { link(i,i+add,k,0); } for(int i=1;i<cnt;i++) { link(i+add,i+1,k,0); } link(head,1,k,0); link(cnt+add,end,k,0); int now,to; int ans=0; for(int i=1;i<=n;i++) { now = mx[x[i]]; to = mx[y[i]]; now++;to--; link(now,to+add,1,y[i]-x[i]); } cout<<ek()<<endl; } return 0; }22 最长k可重线段集问题 最大权不相交路径 最小费用最大流
23 火星探险问题 线性规划网络优化 最小费用最大流
24 骑士共存问题 二分图最大独立集 网络最小割