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
餐巾计划问题 线性规划网络优化
最小费用最大流
11 航空路线问题 最长不相交路径 最小费用最大流12 软件补丁问题 最小转移代价 最短路径13 星际转移问题 网络判定 网络最大流
14 孤岛营救问题 分层图最短路径 最短路径
15 汽车加油行驶问题 分层图最短路径 最短路径
16 数字梯形问题 最大权不相交路径 最小费用最大流
17 运输问题 网络费用流量 最小费用最大流
18 分配问题 二分图最佳匹配 最小费用最大流19 负载平衡问题 最小代价供求 最小费用最大流
20 深海机器人问题 线性规划网络优化 最小费用最大流
21 最长k可重区间集问题 最大权不相交路径 最小费用最大流
22 最长k可重线段集问题 最大权不相交路径 最小费用最大流
23 火星探险问题 线性规划网络优化 最小费用最大流
24 骑士共存问题 二分图最大独立集 网络最小割