您的位置:首页 > 理论基础 > 计算机网络

网络流24题解题报告小结

2015-05-17 13:39 387 查看
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

[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 骑士共存问题
二分图最大独立集 网络最小割
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: