网络流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
最小路径覆盖问题 有向无环图最小路径覆盖
网络最大流
有向无环图最小路径覆盖 网络最大流
二分图多重匹配 网络最大流
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
航空路线问题 最长不相交路径
最小费用最大流
最小转移代价 最短路径
网络判定 网络最大流
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
数字梯形问题 最大权不相交路径
最小费用最大流
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 分配问题
二分图最佳匹配 最小费用最大流
最小代价供求 最小费用最大流
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 骑士共存问题
二分图最大独立集 网络最小割
飞行员配对方案问题 二分图最大匹配
网络最大流
#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 骑士共存问题
二分图最大独立集 网络最小割
相关文章推荐
- 线性规划与网络流24题解题报告
- HOJ 2634 网络流最小割 解题报告
- 网络流24题解题总结(更新中)
- [BZOJ3275]Number解题报告|网络流
- pku 1087 A Plug for UNIX 网络流 解题报告
- SPOJ 1693 网络流最小割 解题报告
- SPOJ IM 962 网络流最大流 解题报告
- 【POJ 2396】 Budget 带上下界网络流 解题报告
- BZOJ 3894 文理分科 解题报告 最小割 网络流 DINIC
- ZOJ 3348 网络流最大流 解题报告
- BZOJ 1822 计算几何+网络流+二分答案 解题报告
- HDU 3572 网络流最大流 解题报告
- ACM -- 算法小结(七)Phone list解题报告
- POJ - 3281 Dining解题报告(网络流 巧妙建图)
- POJ - 1459 Power Network解题报告(网络流最大流 超级源点建图)
- POJ 3281 网络流最大流 解题报告
- POJ - 1149 PIGS解题报告(网络流+巧妙建图)
- Codeforces 808F 网络流最小割(二分图最大点权独立集) 解题报告
- [ZOJ2341]Reactor Cooling解题报告|带上下界的网络流|无源汇的可行流
- LeetCode 148. Sort List 解题报告(归并排序小结)