网络流24题解题报告小结

1 飞行员配对方案问题 二分图最大匹配 网络最大流

#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
 
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FFF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 222;  
const int head = 0;  
const int end = 221;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int id;  
}zx;  
int m,n;  
vector<zz>g[maxn];  
int cen[maxn];  
  
void link(int now,int to,int c,int bc)  
{  
    zx.from = now;  
    zx.to = to;  
    zx.c = c;  
    zx.id = g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to);  
    zx.c = bc;  
    zx.id = g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
bool bfs()  
{  
    MM(cen,-1);  
    queue<int>q;  
    int now,to;  
    q.push(head);  
    cen[head]=0;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(g[now][i].c > 0 && cen[to]==-1)  
            {  
                cen[to]=cen[now]+1;  
                q.push(to);  
            }  
        }  
    }  
    return cen[end]!=-1;  
}  
  
int dfs(int flow = inf,int now = head)  
{  
    if(now == end)  
    {  
        return flow;  
    }  
    int to,sum=0;  
    int temp;  
    for(int i=0;i<g[now].size();i++)  
    {  
        to = g[now][i].to;  
        if(g[now][i].c>0 && flow>sum && cen[to]==cen[now]+1)  
        {  
            temp = dfs(min(flow-sum,g[now][i].c),to);  
            sum+=temp;  
            g[now][i].c-=temp;  
            g[to][g[now][i].id].c+=temp;  
        }  
    }  
    if(!sum) cen[now]=-1;  
    return sum;  
}  
  
int dinic()  
{  
    int ans = 0;  
    while(bfs())  
    {  
        ans+=dfs();  
    }  
    return ans;  
}  
  
int main()  
{  
    int now,to;  
    while(cin>>m>>n)  
    {  
        for(int i=0;i<maxn;i++)  
        {  
            g[i].clear();  
        }  
        while(cin>>now>>to)  
        {  
            if(now==to && now==-1)  
            {  
                break;  
            }  
            else  
            {  
                link(now,to,1,0);  
            }  
        }  
        for(int i=1;i<=m;i++)  
        {  
            link(head,i,1,0);  
        }  
        for(int i=m+1;i<=m+n;i++)  
        {  
            link(i,end,1,0);  
        }  
        cout<<dinic()<<endl;  
        for(int i=1;i<=m;i++)  
        {  
            for(int j=0;j<g[i].size();j++)  
            {  
                if(g[i][j].c==0 && g[i][j].to!=head)  
                {  
                    cout<<i<<" "<<g[i][j].to<<endl;  
                }  
            }  
        }  
    }  
    return 0;  
}  

2 太空飞行计划问题 最大权闭合图 网络最小割

#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
 
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FFF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 222;  
const int add = 111;  
const int head = 0;  
const int end = 221;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int id;  
}zx;  
  
vector<zz>g[maxn];  
int cen[maxn];  
int tot;  
vector<int>v;  
int m,n;  
bool vis[maxn];  
  
void link(int now,int to,int c,int bc)  
{  
    zx.from = now;  
    zx.to = to;  
    zx.c = c;  
    zx.id = g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to);  
    zx.c = bc;  
    zx.id = g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
bool bfs()  
{  
    MM(cen,-1);  
    queue<int>q;  
    cen[head] = 0;  
    q.push(head);  
    int now,to;  
    while(!q.empty())  
    {  
        now=q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(g[now][i].c > 0 && cen[to]==-1)  
            {  
                cen[to] = cen[now]+1;  
                q.push(to);  
            }  
        }  
    }  
    return cen[end]!=-1;  
}  
  
int dfs(int flow = inf,int now = head)  
{  
    if(now == end) return flow;  
    int to,temp,sum=0;  
    for(int i=0;i<g[now].size();i++)  
    {  
        to = g[now][i].to;  
        if(flow>sum && g[now][i].c>0 && cen[to]==cen[now]+1)  
        {  
            temp = dfs(min(g[now][i].c,flow-sum),to);  
            sum += temp;  
            g[now][i].c-=temp;  
            g[to][g[now][i].id].c+=temp;  
        }  
    }  
    if(!sum) cen[now]=-1;  
    return sum;  
}  
  
int dinic()  
{  
    int ans = 0;  
    while(bfs())  
    {  
        ans+=dfs();  
    }  
    return tot-ans;  
}  
  
void find()  
{  
    bfs();  
    MM(vis,false);  
    for(int now=0;now<maxn;now++)  
    {  
        if(cen[now]==-1) continue;  
        for(int i=0;i<g[now].size();i++)  
        {  
            int to = g[now][i].to;  
            if(cen[to]==-1)  
            {  
                if(now == head)  
                {  
                    vis[to]=true;  
                }  
                else if(to == end)  
                {  
                    v.pb(now-add);  
                }  
            }  
        }  
    }  
    return ;  
}  
  
int main()  
{  
    while(cin>>m>>n)  
    {  
        tot=0;  
        for(int i=0;i<maxn;i++)  
        {  
            g[i].clear();  
        }  
        int s,to;  
        for(int now=1;now<=m;now++)  
        {  
            cin>>s;  
            tot+=s;  
            link(head,now,s,0);  
            while(cin.peek()!='\n')  
            {  
                cin>>to;  
                to+=add;  
                link(now,to,inf,0);  
            }  
        }  
        for(int now=1;now<=n;now++)  
        {  
            cin>>s;  
            to = now+add;  
            link(to,end,s,0);  
        }  
        int ans = dinic();  
        v.clear();  
        find();  
        int ti;  
        for(int i=1;i<=m;i++)  
        {  
            if(!vis[i])  
            {  
                ti = i;  
                cout<<i;  
                break;  
            }  
        }  
        for(int i=ti+1;i<=m;i++)  
        {  
            if(!vis[i])  
            {  
                cout<<" "<<i;  
            }  
        }  
        cout<<endl;  
        if(!v.empty()) cout<<v[0];  
        for(int i=1;i<v.size();i++)  
        {  
            cout<<" "<<v[i];  
        }  
        cout<<endl;  
        cout<<ans<<endl;  
    }  
    return 0;  
}  
3 最小路径覆盖问题 有向无环图最小路径覆盖 网络最大流
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
 
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FFF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 555;  
const int add = 222;  
const int head = 0;  
const int end = 551;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int id;  
}zx;  
  
vector<zz>g[maxn];  
int cen[maxn];  
int n,m;  
bool vis[maxn];  
int go[maxn];  
  
void link(int now,int to,int c,int bc)  
{  
    zx.from = now;  
    zx.to = to;  
    zx.c = c;  
    zx.id = g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to);  
    zx.c = bc;  
    zx.id = g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
bool bfs()  
{  
    queue<int>q;  
    MM(cen,-1);  
    cen[head]=0;  
    q.push(head);  
    int now,to;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(cen[to]==-1 && g[now][i].c>0)  
            {  
                cen[to]=cen[now]+1;  
                q.push(to);  
            }  
        }  
    }  
    return cen[end]!=-1;  
}  
  
int dfs(int flow=inf,int now=head)  
{  
    if(now == end) return flow;  
    int to,temp,sum=0;  
    for(int i=0;i<g[now].size();i++)  
    {  
        to = g[now][i].to;  
        if(g[now][i].c>0 && flow>sum && cen[to]==cen[now]+1)  
        {  
            temp = dfs(min(flow-sum,g[now][i].c),to);  
            sum+=temp;  
            g[now][i].c-=temp;  
            g[to][g[now][i].id].c+=temp;  
        }  
    }  
    if(!sum) cen[now] = -1;  
    return sum;  
}  
  
int dinic()  
{  
    int ans = 0;  
    while(bfs())  
    {  
        ans+=dfs();  
    }  
    return ans;  
}  
  
int main()  
{  
    while(cin>>n>>m)  
    {  
        for(int i=0;i<maxn;i++)  
        {  
            g[i].clear();  
        }  
        int now,to;  
        for(int i=1;i<=m;i++)  
        {  
            cin>>now>>to;  
            link(now,to+add,1,0);  
        }  
        for(int i=1;i<=n;i++)  
        {  
            link(head,i,1,0);  
        }  
        for(int i=1+add;i<=n+add;i++)  
        {  
            link(i,end,1,0);  
        }  
        int ans = dinic();  
        ans = n-ans;  
        MM(vis,false);  
        MM(go,0);  
        for(int i=1;i<=n;i++)  
        {  
            for(int j=0;j<g[i].size();j++)  
            {  
                to = g[i][j].to;  
                if(g[i][j].c == 0 && to!=head)  
                {  
                    go[i]=to-add;  
                    vis[to-add]=true;  
                }  
            }  
        }  
        for(int i=1;i<=n;i++)  
        {  
            if(!vis[i])  
            {  
                now = i;  
                cout<<now;  
                while(go[now])  
                {  
                    cout<<" "<<go[now];  
                    now = go[now];  
                }  
                cout<<endl;  
            }  
        }  
        cout<<ans<<endl;  
    }  
    return 0;  
}  
4 魔术球问题 有向无环图最小路径覆盖 网络最大流
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
 
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FFF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 4555;  
const int add = 2222;  
const int end = 4554;  
const int head = 0;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int id;  
}zx;  
  
vector<zz>g[maxn];  
int cen[maxn];  
int n;  
bool vis[maxn];  
int go[maxn];  
bool sq[10001];  
  
void link(int now,int to,int c,int bc)  
{  
    zx.from = now;  
    zx.to = to;  
    zx.c = c;  
    zx.id = g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to);  
    zx.c = bc;  
    zx.id = g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
bool bfs()  
{  
    queue<int>q;  
    MM(cen,-1);  
    cen[head]=0;  
    q.push(head);  
    int now,to;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(cen[to]==-1 && g[now][i].c>0)  
            {  
                cen[to]=cen[now]+1;  
                q.push(to);  
            }  
        }  
    }  
    return cen[end]!=-1;  
}  
  
int dfs(int flow=inf,int now=head)  
{  
    if(now == end) return flow;  
    int to,temp,sum=0;  
    for(int i=0;i<g[now].size();i++)  
    {  
        to = g[now][i].to;  
        if(g[now][i].c>0 && flow>sum && cen[to]==cen[now]+1)  
        {  
            temp = dfs(min(flow-sum,g[now][i].c),to);  
            sum+=temp;  
            g[now][i].c-=temp;  
            g[to][g[now][i].id].c+=temp;  
        }  
    }  
    if(!sum) cen[now] = -1;  
    return sum;  
}  
  
int dinic()  
{  
    int ans = 0;  
    while(bfs())  
    {  
        ans+=dfs();  
    }  
    return ans;  
}  
  
void extend(int x)  
{  
    for(int i=1;i<x;i++)  
    {  
        if(sq[i+x])  
        {  
            link(i,x+add,1,0);  
        }  
    }  
    link(head,x,1,0);  
    link(x+add,end,1,0);  
    return ;  
}  
  
void start()  
{  
    for(int i=0;i<maxn;i++)  
    {  
        g[i].clear();  
    }  
    int flow = 0;  
    int temp = 0;  
    int tot;  
    for(int i=1;temp<=n;i++)  
    {  
        extend(i);  
        flow += dinic();  
        temp = i-flow;  
        tot=i;  
    }  
    tot--;  
    for(int i=0;i<maxn;i++)  
    {  
        g[i].clear();  
    }  
    for(int i=1;i<=tot;i++)  
    {  
        extend(i);  
    }  
    int ans = dinic();  
    MM(vis,false);  
    MM(go,0);  
    int to;  
    for(int i=1;i<=tot;i++)  
    {  
        for(int j=0;j<g[i].size();j++)  
        {  
            to = g[i][j].to;  
            if(to!=head && g[i][j].c == 0)  
            {  
                go[i]=to-add;  
                vis[to-add] = true;  
            }  
        }  
    }  
    int now;  
    cout<<tot<<endl;  
    for(int i=1;i<=tot;i++)  
    {  
        if(!vis[i])  
        {  
            cout<<i;  
            now = i;  
            while(go[now])  
            {  
                cout<<" "<<go[now];  
                now = go[now];  
            }  
            cout<<endl;  
        }  
    }  
    return ;  
}  
  
int main()  
{  
    MM(sq,false);  
    for(int i=1;i<=100;i++)  
    {  
        sq[i*i]=true;  
    }  
    cin>>n;  
    start();  
//  system("pause");  
    return 0;  
}  
5 圆桌问题 二分图多重匹配 网络最大流
6 最长递增子序列问题 最多不相交路径 网络最大流
7 试题库问题 二分图多重匹配 网络最大流
8 机器人路径规划问题 (未解决) 最小费用最大流         byvoid都没做
9 方格取数问题 二分图点权最大独立集 网络最小割

10 餐巾计划问题 线性规划网络优化 最小费用最大流

#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)     memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 2022;  
const int add = 1001;  
const int head = 0;  
const int end = 2021;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int cost;  
    int id;  
}zx;  
  
vector<zz>g[maxn];  
int n,p,m,f,nd,s;  
int r[maxn];  
int way[maxn];  
int bid[maxn];  
bool inq[maxn];  
  
void link(int now,int to,int c,int cost,int bc=0)  
{  
    zx.from = now;zx.to=to;zx.c=c;zx.cost=cost;  
    zx.id = g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to);  
    zx.c=bc;zx.cost=-cost;  
    zx.id = g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
bool spfa()  
{  
    for(int i=0;i<maxn;i++) way[i]=inf;  
    way[head]=0;  
    queue<int>q;  
    MM(inq,false);  
    inq[head]=true;  
    q.push(head);  
    int now,to,temp;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(g[now][i].c>0)  
            {  
                temp = g[now][i].cost+way[now];  
                if(temp<way[to])  
                {  
                    bid[to] = g[now][i].id;  
                    way[to] = temp;  
                    if(!inq[to])  
                    {  
                        inq[to]=true;  
                        q.push(to);  
                    }  
                }  
            }  
        }  
        inq[now]=false;  
    }  
    return way[end]!=inf;  
}  
pair<int,int> dfs(int flow = inf,int to = end)  
{  
    if(to == head) return make_pair(flow,0);  
    int now=g[to][bid[to]].to;  
    int id = g[to][bid[to]].id;  
    pair<int,int>temp=dfs(min(flow,g[now][id].c),now);  
    g[now][id].c-=temp.X;  
    g[to][bid[to]].c+=temp.X;  
    temp.Y+=temp.X*g[now][id].cost;  
    return temp;  
}  
  
int gao()  
{  
    int ans=0;  
    while(spfa())  
    {  
        ans+=dfs().Y;  
    }  
    return ans;  
}  
  
int main()  
{  
    while(cin>>n>>p>>m>>f>>nd>>s)  
    {  
        for(int i=0;i<maxn;i++)  
        {  
            g[i].clear();  
        }  
        for(int i=1;i<=n;i++)  
        {  
            SS(r[i]);  
        }  
        for(int i=1;i<=n;i++)  
        {  
            link(head,i,r[i],0);  
            link(head,i+add,inf,p);  
            link(i+add,end,r[i],0);  
        }  
        int now,to;  
        for(int i=1;i<=n-1;i++)  
        {  
            link(i,i+1,inf,0);  
    //      link(i+add,i+add+1,inf,0);  
        }  
        for(int i=1;i<=n;i++)  
        {  
            now=i;to=i+add+m;  
            if(to<=add+n) link(now,to,inf,f);  
            now=i;to=i+add+nd;  
            if(to<=add+n) link(now,to,inf,s);  
        }  
        cout<<gao()<<endl;  
    }  
    return 0;  
}  
11 航空路线问题 最长不相交路径 最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)         memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 2111;  
const int add = 1001;  
const int head = 0;  
const int end = 2110;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int cost;  
    int id;  
}zx;  
  
string s[maxn];  
map<string,int>ms;  
int n,m;  
vector<zz>g[maxn];  
vector<int>v;  
vector<int>v2;  
int way[maxn];  
bool inq[maxn];  
int bid[maxn];  
  
void link(int now,int to,int c,int cost,int bc=0)  
{  
    zx.from=now;zx.to=to;zx.c=c;zx.cost=cost;  
    zx.id=g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to);  
    zx.c=bc;zx.cost=-cost;  
    zx.id=g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
bool spfa()  
{  
    for(int i=0;i<maxn;i++)  
    {  
        way[i]=-inf;  
    }  
    way[head]=0;  
    deque<int>q;  
    MM(inq,false);  
    inq[head]=true;  
    q.pb(head);  
    int now,to,temp;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop_front();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(g[now][i].c>0)  
            {  
                temp = g[now][i].cost+way[now];  
                if(temp>way[to])  
                {  
                    bid[to] = g[now][i].id;  
                    way[to] = temp;  
                    if(!inq[to])  
                    {  
                        inq[to]=true;  
                //      if(q.empty() || way[to]<way[q.front()]) q.pf(to);  //最小费用流  
                //      else  
                        if(q.empty() || way[to]>way[q.front()]) q.pf(to);  //最大费用流  
                        else  
                        q.pb(to);  
                    }  
                }  
            }  
        }  
        inq[now]=false;  
    }  
    return way[end]!=-inf;  
}  
pair<int,int> dfs(int flow = inf,int to = end)  
{  
    if(to == head) return make_pair(flow,0);  
    int now=g[to][bid[to]].to;  
    int id = g[to][bid[to]].id;  
    pair<int,int>temp=dfs(min(flow,g[now][id].c),now);  
    g[now][id].c-=temp.X;  
    g[to][bid[to]].c+=temp.X;  
    temp.Y+=temp.X*g[now][id].cost;  
    return temp;  
}  
  
  
bool gao()  
{  
    pair<int,int>ans,temp;  
    ans.X=ans.Y=0;  
    while(spfa())  
    {  
        temp = dfs();  
        ans.X+=temp.X;  
        ans.Y+=temp.Y;  
    }  
    if(ans.X==2)  
    {  
        int now = 1;  
        int to;  
        v.clear();  
        v2.clear();  
        v.pb(now);  
        while(now!=n)  
        {  
            now+=add;  
            for(int i=0;i<g[now].size();i++)  
            {  
                to = g[now][i].to;  
                if(g[now][i].c<2 && to!=now-add)  
                {  
                    g[now][i].c++;  
                    v.pb(to);  
                    now = to;  
                    break;  
                }  
            }  
        }  
        now = 1;  
        v2.pb(now);  
        while(now!=n)  
        {  
            now+=add;  
            for(int i=0;i<g[now].size();i++)  
            {  
                to = g[now][i].to;  
                if(g[now][i].c<2 && to!=now-add)  
                {  
                    g[now][i].c++;  
                    v2.pb(to);  
                    now = to;  
                    break;  
                }  
            }  
        }  
        v2.pop_back();  
        cout<<ans.Y<<endl;  
        return true;  
    }  
    return false;  
}  
  
  
int main()  
{  
    while(cin>>n>>m)  
    {  
        ms.clear();  
        for(int i=0;i<maxn;i++)  
        {  
            g[i].clear();  
        }  
        for(int i=1;i<=n;i++)  
        {  
            cin>>s[i];  
        }  
        for(int i=1;i<=n;i++)  
        {  
            link(i,i+add,1,1);  
        }  
        link(1,1+add,1,0);  
        link(n,n+add,1,0);  
        link(head,1,2,0);  
        link(n+add,end,2,0);  
          
        for(int i=1;i<=n;i++)  
        {  
            ms[s[i]]=i;  
        }  
        string sa,sb;  
        int now,to;  
        for(int i=1;i<=m;i++)  
        {  
            cin>>sa>>sb;  
            now = ms[sa];  
            to = ms[sb];  
            if(now>to) swap(now,to);  
            link(now+add,to,2,0);  
        }  
        if(gao())  
        {  
            for(int i=0;i<v.size();i++)  
            {  
                cout<<s[v[i]]<<endl;  
            }  
            int size = v2.size()-1;  
            for(int i=size;i>=0;i--)  
            {  
                cout<<s[v2[i]]<<endl;  
            }  
        }  
        else  
        {  
            cout<<"No Solution!"<<endl;  
        }  
    }  
    return 0;  
}  
12 软件补丁问题 最小转移代价 最短路径
#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)     memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 1<<20;  
const int maxz = 111;  
  
  
struct zz  
{  
    int from;  
    int to;  
    int cost;  
}zx;  
  
int dp[maxn];  
int n,m;  
int b[maxz];  
int b2[maxz];  
int f[maxz];  
int f2[maxz];  
int t[maxz];  
vector<zz>g[maxn];  
  
inline void link(int& now,int& to,int& cost)  
{  
    zx.from = now;  
    zx.to = to;  
    zx.cost = cost;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
int find(string &s)  
{  
    int re=0;  
    int temp;  
    for(int i=0;i<s.length();i++)  
    {  
        if(s[i]=='+')  
        {  
            temp = 1<<i;  
            re+=temp;  
        }  
    }  
    return re;  
}  
  
int find2(string &s)  
{  
    int re=0;  
    int temp;  
    for(int i=0;i<s.length();i++)  
    {  
        if(s[i]=='-')  
        {  
            temp = 1<<i;  
            re+= temp;  
        }  
    }  
    return re;  
}  
  
bool inq[maxn];  
  
int spfa()  
{  
    queue<int>q;  
    MM(inq,false);  
    for(int i=0;i<(1<<n);i++)  
    {  
        dp[i]=inf;  
    }  
    dp[0]=0;  
    inq[0] = true;  
    q.push(0);  
    int now,to,temp;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            temp = dp[now]+g[now][i].cost;  
            if(temp<dp[to])  
            {  
                dp[to] =temp;  
                if(!inq[to])  
                {  
                    inq[to]=true;  
                    q.push(to);  
                }  
            }  
        }  
        inq[now]=false;  
    }  
    return dp[(1<<n)-1];  
}  
  
  
int main()  
{  
    string sa,sb;  
    while(cin>>n>>m)  
    {  
        for(int i=0;i<(1<<n);i++)  
        {  
            g[i].clear();  
        }  
        for(int i=1;i<=m;i++)  
        {  
            cin>>t[i]>>sa>>sb;  
            b[i] = find(sa);  
            b2[i] = find2(sa);  
            f[i] = find2(sb);  
            f2[i] = find(sb);  
        }  
        int now,to,temp;  
        for(int i=0;i<(1<<n);i++)  
        {  
            for(int j=1;j<=m;j++)  
            {  
                if(i & b[j])    continue;  
                now = ~i;  
                if(now & b2[j]) continue;  
                now = i;  
                to = now | f[j];  
                temp = ~f2[j];  
                to &= temp;  
                link(now,to,t[j]);  
            }  
        }  
        int ans = spfa();  
        if(ans!=inf)  
        {  
            cout<<ans<<endl;  
        }  
        else  
        {  
            cout<<"0"<<endl;  
        }  
    }  
    return 0;  
}  
13 星际转移问题 网络判定 网络最大流
#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)     memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 5111;  
const int maxm = 22;  
const int end = 5110;  
const int head = 0;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int id;  
}zx;  
  
int n,m,k;  
vector<zz>g[maxn];  
int c[maxm];  
vector<int>v[maxm];  
int p[maxm];  
int back[maxn];  
bool inq[maxn];  
int f[maxm];  
  
void link(int now,int to,int c,int bc=0)  
{  
    zx.from = now;zx.to=to;zx.c=c;zx.id=g[zx.to].size();g[zx.from].pb(zx);  
    swap(zx.from,zx.to);zx.id=g[zx.to].size()-1;zx.c=bc;g[zx.from].pb(zx);  
    return ;  
}  
  
bool bfs()  
{  
    MM(inq,false);  
    queue<int>q;  
    back[head]=back[end]=-1;  
    inq[head]=true;  
    q.push(head);  
    int now,to,temp;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(g[now][i].c>0)  
            {  
                if(!inq[to])  
                {  
                    inq[to]=true;  
                    back[to]=g[now][i].id;  
                    q.push(to);  
                }  
            }  
        }  
        if(inq[end]) break;  
    }  
    return back[end]!=-1;  
}  
  
int dfs(int flow = inf,int to = end)  
{  
    if(to == head) return flow;  
    int now = g[to][back[to]].to;  
    int id = g[to][back[to]].id;  
    int re = dfs(min(flow,g[now][id].c),now);  
    g[now][id].c-=re;  
    g[to][back[to]].c+=re;  
    return re;  
}  
  
int ek()  
{  
    int re = 0;  
    while(bfs())  
    {  
        re+=dfs();  
    }  
    return re;  
}  
  
int num(int day,int x)  
{  
    return (n+1)*day + x;  
}  
  
void add(int day)  
{  
    int now,to,temp;  
    for(int i=1;i<=m;i++)  
    {  
        temp = day%p[i];  
        if(!temp) now = v[i].back();  
        else now = v[i][temp-1];  
        to = v[i][temp];  
        if(now!=-1)  
        {  
            if(to == -1)  
            {  
                link(num(day-1,now),end,c[i]);  
            }  
            else  
            {  
                link(num(day-1,now),num(day,to),c[i]);  
            }  
        }  
    }  
    for(int i=0;i<=n;i++)  
    {  
        link(num(day-1,i),num(day,i),inf);  
    }  
    return ;  
}  
  
int start()  
{  
    int flow=0;  
    int ans;  
    for(ans=1;flow<k;ans++)  
    {  
        add(ans);  
        flow += ek();  
    }  
    return ans-1;  
}  
  
int find(int x)  
{  
    if(x!=f[x])  
    return f[x]=find(f[x]);  
  
    return x;  
}  
  
int main()  
{  
    while(cin>>n>>m>>k)  
    {  
        for(int i=0;i<maxm;i++) f[i]=i;  
        for(int i=0;i<maxn;i++)  g[i].clear();  
        for(int i=0;i<maxm;i++) v[i].clear();  
        for(int i=1;i<=m;i++)  
        {  
            cin>>c[i]>>p[i];  
            int temp;  
            int pre,t2;  
            for(int x=1;x<=p[i];x++)  
            {  
                cin>>temp;  
                v[i].pb(temp);  
                if(temp==-1)  
                {  
                    t2 = n+1;  
                }  
                else t2 = temp;  
                if(x>=2)  
                {  
                    f[find(pre)]=find(t2);  
                }  
                pre = t2;  
            }  
            f[find(pre)]=find(v[i][0]);  
        }  
        if(find(0)!=find(n+1))  
        {  
            cout<<"0"<<endl;  
        }  
        else  
        {  
            cout<<start()<<endl;  
        }  
    }  
    return 0;  
}  

14 孤岛营救问题 分层图最短路径 最短路径

#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)     memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxs = 1<<11;  
const int maxn = 222;  
const int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};  
struct zz  
{  
    int x;  
    int s;  
}zx;  
int head,end;  
int dp[maxn][maxs];  
int f[maxn];  
int go[maxn][4];  
int n,m,p,k,s;  
  
int num(int x,int y)  
{  
    return (x-1)*m+y;  
}  
  
int getx(int temp)  
{  
    return (temp-1)/m+1;  
}  
  
int gety(int temp)  
{  
    return (temp-1)%m+1;  
}  
  
bool yes(int x,int y)  
{  
    if(x>=1 && x<=n && y>=1 && y<= m)  
    return true;  
    return false;  
}  
  
int fd(int dx,int dy)  
{  
    if(dx==-1)  
    {  
        return 0;  
    }  
    if(dx==1)  
    {  
        return 1;  
    }  
    if(dy==-1)  
    {  
        return 2;  
    }  
    if(dy==1)  
    {  
        return 3;  
    }  
    assert(false);  
}  
  
bool inq[maxn][maxs];  
  
int spfa()  
{  
    zz now,to;  
    queue<zz>q;  
    MM(inq,false);  
    now.x = num(1,1);  
    now.s = f[num(1,1)];  
    inq[now.x][now.s]=true;  
    dp[now.x][now.s]=0;  
    q.push(now);  
    int x,y;  
    int temp;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<4;i++)  
        {  
            if(go[now.x][i]!=-1 && !(~now.s & go[now.x][i]) )  
            {  
                x=getx(now.x)+dir[i][0];  
                y=gety(now.x)+dir[i][1];  
                if(yes(x,y))  
                {  
                    to.x = num(x,y);  
                    to.s = now.s | f[to.x];  
                    temp = dp[now.x][now.s]+1;  
                    if(dp[to.x][to.s]>temp)  
                    {  
                        dp[to.x][to.s] = temp;  
                        if(!inq[to.x][to.s])  
                        {  
                            inq[to.x][to.s]=true;  
                            q.push(to);  
                        }  
                    }  
                }  
            }  
        }  
        inq[now.x][now.s]=false;  
    }  
    int ans=inf;  
    for(int i=0;i<(1<<p);i++)  
    {  
        ans=min(ans,dp[num(n,m)][i]);  
    }  
    if(ans == inf) return -1;  
    return ans;  
}  
  
int main()  
{  
    while(cin>>n>>m>>p)  
    {  
        for(int i=0;i<maxn;i++)  
        {  
            for(int j=0;j<(1<<p);j++)  
            {  
                dp[i][j]=inf;  
            }  
        }  
        MM(go,0);  
        MM(f,0);  
        cin>>k;  
        int x,y,x2,y2,temp;  
        for(int i=1;i<=k;i++)  
        {  
            cin>>x>>y>>x2>>y2>>temp;  
            if(temp==0)  
            {  
                go[num(x,y)][fd(x2-x,y2-y)]=-1;  
                go[num(x2,y2)][fd(x-x2,y-y2)]=-1;  
            }  
            else  
            {  
                temp--;  
                go[num(x,y)][fd(x2-x,y2-y)]=(1<<temp);  
                go[num(x2,y2)][fd(x-x2,y-y2)]=(1<<temp);  
            }  
        }  
        cin>>s;  
        for(int i=1;i<=s;i++)  
        {  
            cin>>x>>y>>temp;  
            temp--;  
            f[num(x,y)]|=(1<<temp);  
        }  
        cout<<spfa()<<endl;  
    }  
    return 0;  
}  

15 汽车加油行驶问题 分层图最短路径 最短路径

#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)     memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};  
const int maxn = 111;  
  
struct zz  
{  
    int x;  
    int y;  
    int s;  
}zx;  
  
int n,k,a,b,c;  
int ary[maxn][maxn];  
int dp[maxn][maxn][11];  
bool inq[maxn][maxn][11];  
  
bool yes(int x,int y)  
{  
    if(x>=1 && x<=n && y>=1 && y<=n)  
    return true;  
    return false;  
}  
  
int spfa()  
{  
    queue<zz>q;  
    zx.x = zx.y =1;  
    zx.s = k;  
    inq[zx.x][zx.y][zx.s]=true;  
    dp[zx.x][zx.y][zx.s]=0;  
    q.push(zx);  
    zz now,to;  
    int temp,add,ts;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        if(now.s == 0)  
        {  
            ts=k;  
            add = a+c;  
        }  
        else  
        {  
            ts=now.s;  
            add=0;  
        }  
        for(int i=0;i<2;i++)  
        {  
            to.x = now.x + dir[i][0];  
            to.y = now.y + dir[i][1];  
            to.s = ts - 1;  
            if(yes(to.x,to.y))  
            {  
                temp = dp[now.x][now.y][now.s]+add;  
                if(ary[to.x][to.y])  
                {  
                    temp+=a;  
                    to.s = k;  
                }  
                if(temp<dp[to.x][to.y][to.s])  
                {  
                    dp[to.x][to.y][to.s] = temp;  
                    if(!inq[to.x][to.y][to.s])  
                    {  
                        inq[to.x][to.y][to.s] = true;  
                        q.push(to);  
                    }  
                }  
            }  
        }  
        add+=b;  
        for(int i=2;i<4;i++)  
        {  
            to.x = now.x + dir[i][0];  
            to.y = now.y + dir[i][1];  
            to.s = ts - 1;  
            if(yes(to.x,to.y))  
            {  
                temp = dp[now.x][now.y][now.s]+add;  
                if(ary[to.x][to.y])  
                {  
                    temp+=a;  
                    to.s = k;  
                }  
                if(temp<dp[to.x][to.y][to.s])  
                {  
                    dp[to.x][to.y][to.s] = temp;  
                    if(!inq[to.x][to.y][to.s])  
                    {  
                        inq[to.x][to.y][to.s] = true;  
                        q.push(to);  
                    }  
                }  
            }  
        }  
        inq[now.x][now.y][now.s]=false;  
    }  
    int re=inf;  
    for(int i=0;i<=k;i++)  
    {  
        re=min(re,dp[n][n][i]);  
    }  
    if(re==inf) return -1;  
    return re;  
}  
  
int start()  
{  
    for(int i=1;i<=n;i++)  
    {  
        for(int j=1;j<=n;j++)  
        {  
            for(int x=0;x<=k;x++)  
            {  
                dp[i][j][x]=inf;  
                inq[i][j][x]=false;  
            }  
        }  
    }  
    return spfa();  
}  
  
  
int main()  
{  
    while(cin>>n>>k>>a>>b>>c)  
    {  
        for(int i=1;i<=n;i++)  
        {  
            for(int j=1;j<=n;j++)  
            {  
                cin>>ary[i][j];  
            }  
        }  
        cout<<start()<<endl;  
    }  
    return 0;  
}  
16 数字梯形问题 最大权不相交路径 最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)         memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 822;  
const int add = 411;  
const int head = 0;  
const int end = 821;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int cost;  
    int id;  
}zx;  
  
int a[22][22];  
int n,m;  
vector<zz>g[maxn];  
int way[maxn];  
int back[maxn];  
  
void link(int now,int to,int c,int cost,int bc = 0)  
{  
    zx.from = now;  
    zx.to = to;  
    zx.c = c;  
    zx.cost = cost;  
    zx.id = g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to);  
    zx.c = bc;  
    zx.cost = -cost;  
    zx.id = g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
int num(int x,int y)  
{  
    return (x-1)*20+y;  
}  
  
void build(int ax=1,int bx=1)  
{  
    for(int i=0;i<maxn;i++)  
    {  
        g[i].clear();  
    }  
    int now,to;  
    for(int i=1;i<=m;i++)  
    {  
        now = num(1,i);  
        link(head,now,1,0);  
    }  
    for(int i=1;i<=n;i++)  
    {  
        for(int j=1;j<i+m;j++)  
        {  
            link(num(i,j),num(i,j)+add,ax,a[i][j]);  
        }  
    }  
    for(int i=1;i<n;i++)  
    {  
        for(int j=1;j<i+m;j++)  
        {  
            link(num(i,j)+add,num(i+1,j),bx,0);  
            link(num(i,j)+add,num(i+1,j+1),bx,0);  
        }  
    }  
    for(int i=1;i<n+m;i++)  
    {  
        link(num(n,i)+add,end,inf,0);  
    }  
    return ;  
}  
  
bool inq[maxn];  
  
int spfa()  
{  
    MM(way,-1);  
    MM(back,-1);  
    deque<int>q;  
    q.clear();  
    MM(inq,false);  
    inq[head] = true;  
    q.push_back(head);  
    way[head] = 0;  
    int now,to,temp;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop_front();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(g[now][i].c>0)  
            {  
                temp = g[now][i].cost+way[now];  
                if(temp>way[to])  
                {  
                    back[to]=g[now][i].id;  
                    way[to]=temp;  
                    if(!inq[to])  
                    {  
                        inq[to]=true;  
                        if(q.empty() || temp>way[q.front()]) q.pf(to);  
                        else q.pb(to);  
                    }  
                }  
            }  
        }  
        inq[now]=false;  
    }  
    return way[end]!=-1;  
}  
  
pair<int,int> dfs(int flow=inf,int to=end)  
{  
    if(to == head) return make_pair(flow,0);  
    int now = g[to][back[to]].to;  
    int id  = g[to][back[to]].id;  
    pair<int,int>temp = dfs(min(g[now][id].c,flow),now);  
    g[now][id].c-=temp.X;  
    g[to][back[to]].c+=temp.X;  
    temp.Y+=temp.X*g[now][id].cost;  
    return temp;  
}  
  
int ek()  
{  
    int re=0;  
    while(spfa())  
    {  
        re+=dfs().Y;  
    }  
    return re;  
}  
  
void start()  
{  
    build(1,1);  
    cout<<ek()<<endl;  
    build(inf,1);  
    cout<<ek()<<endl;  
    build(inf,inf);  
    cout<<ek()<<endl;  
    return ;  
}  
  
int main()  
{  
    while(cin>>m>>n)  
    {  
        for(int i=1;i<=n;i++)  
        {  
            for(int j=1;j<i+m;j++)  
            {  
                cin>>a[i][j];  
            }  
        }  
        start();  
    }  
    return 0;  
}  

17 运输问题 网络费用流量 最小费用最大流

#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)         memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 222;  
const int head = 0;  
const int end = 221;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int cost;  
    int id;  
}zx;  
  
vector<zz>g[maxn];  
int m,n;  
int a[maxn];  
bool inq[maxn];  
int way[maxn];  
int back[maxn];  
int f[maxn][maxn];  
  
void link(int now,int to,int c,int cost,int bc=0)  
{  
    zx.from = now; zx.to=to; zx.c=c; zx.cost=cost; zx.id=g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to); zx.c=bc; zx.cost=-cost; zx.id=g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
bool spfa(bool x)  
{  
    if(x)  
    {  
        for(int i=0;i<maxn;i++)  
        {  
            way[i]=-inf;  
        }  
    }  
    else  
    {  
        for(int i=0;i<maxn;i++)  
        {  
            way[i]=inf;  
        }  
    }  
    MM(back,-1);  
    queue<int>q;  
    MM(inq,false);  
    inq[head]=true;  
    way[head]=0;  
    q.push(head);  
    int now,to,temp;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(g[now][i].c>0)  
            {  
                temp = g[now][i].cost + way[now];  
                if(x)  
                {  
                    if(temp>way[to])  
                    {  
                        back[to] = g[now][i].id;  
                        way[to]=temp;  
                        if(!inq[to])  
                        {  
                            inq[to]=true;  
                            q.push(to);  
                        }  
                    }  
                }  
                else  
                {  
                    if(temp<way[to])  
                    {  
                        back[to]=g[now][i].id;  
                        way[to]=temp;  
                        if(!inq[to])  
                        {  
                            inq[to]=true;  
                            q.push(to);  
                        }  
                    }  
                }  
            }  
        }  
        inq[now]=false;  
    }  
    if(x)  
    {  
        return way[end]!=-inf;  
    }  
    else  
    {  
        return way[end]!=inf;  
    }  
}  
  
int dfs(int flow=inf,int to=end)  
{  
    if(to == head) return flow;  
    int now = g[to][back[to]].to;  
    int id = g[to][back[to]].id;  
    int re = dfs(min(flow,g[now][id].c),now);  
    g[now][id].c-=re;  
    g[to][back[to]].c+=re;  
    return re;  
}  
  
int ek(bool x)  
{  
    int ans = 0;  
    while(spfa(x))  
    {  
        ans+=dfs()*way[end];  
    }  
    return ans;  
}  
  
void build()  
{  
    for(int i=0;i<maxn;i++)  
    {  
        g[i].clear();  
    }  
    for(int i=1;i<=m;i++)  
    {  
        link(head,i,a[i],0);  
    }  
    for(int i=m+1;i<=m+n;i++)  
    {  
        link(i,end,a[i],0);  
    }  
    int cost;  
    for(int i=1;i<=m;i++)  
    {  
        for(int j=m+1;j<=m+n;j++)  
        {  
            link(i,j,inf,f[i][j]);  
        }  
    }  
    return ;  
}  
  
int main()  
{  
    while(cin>>m>>n)  
    {  
        for(int i=1;i<=m;i++)  
        {  
            cin>>a[i];  
        }  
        for(int i=1+m;i<=n+m;i++)  
        {  
            cin>>a[i];  
        }  
        for(int i=1;i<=m;i++)  
        {  
            for(int j=m+1;j<=m+n;j++)  
            {  
                cin>>f[i][j];  
            }  
        }  
        build();  
        cout<<ek(false)<<endl;  
        build();  
        cout<<ek(true)<<endl;  
    }  
    return 0;  
}  

18 分配问题 二分图最佳匹配 最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)         memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 222;  
const int head = 0;  
const int end = 221;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int cost;  
    int id;  
}zx;  
  
int n;  
vector<zz>g[maxn];  
int cx[maxn][maxn];  
  
void link(int now,int to,int c,int cost,int bc=0)  
{  
    zx.from = now,zx.to =to,zx.c = c,zx.cost=cost;  
    zx.id = g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to),zx.c = bc,zx.cost = -cost;  
    zx.id = g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
int way[maxn];  
bool inq[maxn];  
int back[maxn];  
  
bool spfa(bool x)  
{  
    if(x) for(int i=0;i<maxn;i++) way[i] = inf;  
    else for(int i=0;i<maxn;i++) way[i] = -inf;  
    queue<int>q;  
    inq[head]=true;  
    q.push(head);  
    way[head]=0;  
    int now,to,temp;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(g[now][i].c>0)  
            {  
                temp = way[now]+g[now][i].cost;  
                if(x)  
                {  
                    if(temp<way[to])  
                    {  
                        way[to]=temp;  
                        back[to]=g[now][i].id;  
                        if(!inq[to])  
                        {  
                            inq[to]=true;  
                            q.push(to);  
                        }  
                    }  
                }  
                else  
                {  
                    if(temp>way[to])  
                    {  
                        way[to]=temp;  
                        back[to]=g[now][i].id;  
                        if(!inq[to])  
                        {  
                            inq[to]=true;  
                            q.push(to);  
                        }  
                    }  
                }  
            }  
        }  
        inq[now]=false;  
    }  
    if(x) return way[end]!=inf;  
    else return way[end]!=-inf;  
}  
  
int dfs(int flow=inf,int to=end)  
{  
    if(to==head) return flow;  
    int now = g[to][back[to]].to;  
    int id  = g[to][back[to]].id;  
    int temp = dfs(min(flow,g[now][id].c),now);  
    g[now][id].c-=temp;  
    g[to][back[to]].c+=temp;  
    return temp;  
}  
  
int ek(bool x)  
{  
    int ans=0;  
    while(spfa(x))  
    {  
        ans+=dfs()*way[end];  
    }  
    return ans;  
}  
  
void build()  
{  
    for(int i=0;i<maxn;i++)  
    {  
        g[i].clear();  
    }  
    for(int i=1;i<=n;i++)  
    {  
        for(int j=n+1;j<=n+n;j++)  
        {  
            link(i,j,1,cx[i][j]);  
        }  
    }  
    for(int i=1;i<=n;i++)  
    {  
        link(head,i,1,0);  
    }  
    for(int i=n+1;i<=n+n;i++)  
    {  
        link(i,end,1,0);  
    }  
    return ;  
}  
  
int main()  
{  
    while(cin>>n)  
    {  
        for(int i=1;i<=n;i++)  
        {  
            for(int j=n+1;j<=n+n;j++)  
            {  
                cin>>cx[i][j];  
            }  
        }  
        build();  
        cout<<ek(true)<<endl;  
        build();  
        cout<<ek(false)<<endl;  
    }  
    return 0;  
}  
19 负载平衡问题 最小代价供求 最小费用最大流
#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)         memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 222;  
const int head = 0;  
const int end = 221;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int cost;  
    int id;  
}zx;  
  
vector<zz>g[maxn];  
int n;  
  
int dis(int x,int y)  
{  
    if(x>y) swap(x,y);  
    int re = y-x;  
    re = min(n-re,re);  
    return re;  
}  
  
int way[maxn];  
bool inq[maxn];  
int back[maxn];  
  
void link(int now,int to,int c,int cost,int bc=0)  
{  
    zx.from=now,zx.to=to,zx.c=c,zx.cost=cost;  
    zx.id=g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to);zx.c=bc,zx.cost=-cost;  
    zx.id=g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
  
bool spfa()  
{  
    MM(inq,false);  
    MM(back,-1);  
    for(int i=0;i<maxn;i++) way[i]=inf;  
    queue<int>q;  
    way[head]=0;  
    inq[head]=true;  
    q.push(head);  
    int now,to,temp;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(g[now][i].c>0)  
            {  
                temp = way[now]+g[now][i].cost;  
                if(temp<way[to])  
                {  
                    way[to]=temp;  
                    back[to]=g[now][i].id;  
                    if(!inq[to])  
                    {  
                        inq[to]=true;  
                        q.push(to);  
                    }  
                }  
            }  
        }  
        inq[now]=false;  
    }  
    return way[end]!=inf;  
}  
  
int dfs(int flow=inf,int to=end)  
{  
    if(to==head) return flow;  
    int now = g[to][back[to]].to;  
    int id = g[to][back[to]].id;  
    int temp = dfs(min(flow,g[now][id].c),now);  
    g[now][id].c-=temp;  
    g[to][back[to]].c+=temp;  
    return temp;  
}  
  
int ek()  
{  
    int ans=0;  
    while(spfa())  
    {  
        ans+=dfs()*way[end];  
    }  
    return ans;  
}  
  
int main()  
{  
    int temp,sum=0;  
    while(cin>>n)  
    {  
        for(int i=0;i<maxn;i++) g[i].clear();  
        for(int i=1;i<=n;i++)  
        {  
            for(int j=1;j<=n;j++)  
            {  
                link(i,j+n,inf,dis(i,j));  
            }  
        }  
        for(int i=1;i<=n;i++)  
        {  
            cin>>temp;  
            sum+=temp;  
            link(head,i,temp,0);  
        }  
        sum/=n;  
        for(int i=n+1;i<=n+n;i++)  
        {  
            link(i,end,sum,0);  
        }  
        cout<<ek()<<endl;  
    }  
  
    return 0;  
}  

20 深海机器人问题 线性规划网络优化 最小费用最大流

#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)         memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
const int maxn = 333;  
const int head = 0;  
const int end = 332;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int cost;  
    int id;  
}zx;  
  
vector<zz>g[maxn];  
int ax,bx,n,m;  
  
  
int num(int x,int y)  
{  
    return (x-1)*(m+1)+y;  
}  
  
int way[maxn];  
bool inq[maxn];  
int back[maxn];  
  
void link(int now,int to,int c,int cost,int bc=0)  
{  
    zx.from=now;zx.to=to;zx.c=c;zx.cost=cost;  
    zx.id = g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to);zx.c=bc;zx.cost=-cost;  
    zx.id = g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
bool spfa()  
{  
    MM(inq,false);  
    MM(back,-1);  
    for(int i=0;i<maxn;i++) way[i]=-inf;  
    queue<int>q;  
    q.push(head);  
    inq[head]=true;  
    way[head]=0;  
    int now,to,temp;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(g[now][i].c>0)  
            {  
                temp = way[now]+g[now][i].cost;  
                if(temp>way[to])  
                {  
                    way[to]=temp;  
                    back[to]=g[now][i].id;  
                    if(!inq[to])  
                    {  
                        inq[to]=true;  
                        q.push(to);  
                    }  
                }  
            }  
        }  
        inq[now]=false;  
    }  
    return way[end]!=-inf;  
}  
  
int dfs(int flow=inf,int to=end)  
{  
    if(to==head) return flow;  
    int now=g[to][back[to]].to;  
    int id =g[to][back[to]].id;  
    int temp = dfs(min(flow,g[now][id].c),now);  
    g[now][id].c-=temp;  
    g[to][back[to]].c+=temp;  
    return temp;  
}  
  
int ek()  
{  
    int ans=0;  
    while(spfa())  
    {  
        ans+=dfs()*way[end];  
    }  
    return ans;  
}  
  
int main()  
{  
    while(cin>>ax>>bx)  
    {  
        cin>>n>>m;  
        int temp;  
        for(int i=1;i<=n+1;i++)  
        {  
            for(int j=1;j<=m;j++)  
            {  
                cin>>temp;  
                link(num(i,j),num(i,j+1),1,temp);  
                link(num(i,j),num(i,j+1),inf,0);  
            }  
        }  
        for(int i=1;i<=m+1;i++)  
        {  
            for(int j=1;j<=n;j++)  
            {  
                cin>>temp;  
                link(num(j,i),num(j+1,i),1,temp);  
                link(num(j,i),num(j+1,i),inf,0);  
            }  
        }  
        int x,y;  
        for(int i=1;i<=ax;i++)  
        {  
            cin>>temp>>x>>y;  
            x++;y++;  
            link(head,num(x,y),temp,0);  
        }  
        for(int i=1;i<=bx;i++)  
        {  
            cin>>temp>>x>>y;  
            x++;y++;  
            link(num(x,y),end,temp,0);  
        }  
        cout<<ek()<<endl;  
    }  
    return 0;  
}  

21 最长k可重区间集问题 最大权不相交路径 最小费用最大流

#pragma comment(linker, "/STACK:102400000,102400000")  
#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
using namespace std;  
#ifdef _WIN32  
#define i64 __int64  
#define out64 "%I64d\n"  
#define in64 "%I64d"  
#else  
#define i64 long long  
#define out64 "%lld\n"  
#define in64 "%lld"  
#endif  
/************ for topcoder by zz1215 *******************/  
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  
#define FF(i,a)        for( int i = 0 ; i < (a) ; i ++)  
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  
#define S64(a)          scanf(in64,&a)  
#define SS(a)           scanf("%d",&a)  
#define LL(a)           ((a)<<1)  
#define RR(a)           (((a)<<1)+1)  
#define pb              push_back  
#define pf              push_front  
#define X               first  
#define Y               second  
#define CL(Q)           while(!Q.empty())Q.pop()  
#define MM(name,what)   memset(name,what,sizeof(name))  
#define MC(a,b)         memcpy(a,b,sizeof(b))  
#define MAX(a,b)        ((a)>(b)?(a):(b))  
#define MIN(a,b)        ((a)<(b)?(a):(b))  
#define read            freopen("in.txt","r",stdin)  
#define write           freopen("out.txt","w",stdout)  
  
const int inf = 0x3f3f3f3f;  
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  
const double oo = 10e9;  
const double eps = 10e-9;  
const double pi = acos(-1.0);  
  
const int maxn = 4111;  
const int head = 0;  
const int add =  2011;  
const int end = 4110;  
  
struct zz  
{  
    int from;  
    int to;  
    int c;  
    int cost;  
    int id;  
}zx;  
  
int n,k;  
int x[maxn];  
int y[maxn];  
map<int,int>mx;  
vector<int>v,vx;  
vector<zz>g[maxn];  
  
void link(int now,int to,int c,int cost,int bc=0)  
{  
    zx.from=now;zx.to=to;zx.c=c;zx.cost=cost;  
    zx.id=g[zx.to].size();  
    g[zx.from].pb(zx);  
    swap(zx.from,zx.to);zx.c=bc;zx.cost=-cost;  
    zx.id=g[zx.to].size()-1;  
    g[zx.from].pb(zx);  
    return ;  
}  
  
int way[maxn];  
bool inq[maxn];  
int back[maxn];  
  
bool spfa()  
{  
    for(int i=0;i<maxn;i++) way[i]=-inf;  
    MM(inq,false);  
    MM(back,-1);  
    queue<int>q;  
    inq[head]=true;  
    way[head]=0;  
    q.push(head);  
    int now,to,temp;  
    while(!q.empty())  
    {  
        now = q.front();  
        q.pop();  
        for(int i=0;i<g[now].size();i++)  
        {  
            to = g[now][i].to;  
            if(g[now][i].c>0)  
            {  
                temp = way[now]+g[now][i].cost;  
                if(temp>way[to])  
                {  
                    way[to] = temp;  
                    back[to]=g[now][i].id;  
                    if(!inq[to])  
                    {  
                        inq[to]=true;  
                        q.push(to);  
                    }  
                }  
            }  
        }  
        inq[now]=false;  
    }  
    return way[end]!=-inf;  
}  
  
int dfs(int flow=inf,int to=end)  
{  
    if(to==head)  
    {  
        return flow;  
    }  
    int now = g[to][back[to]].to;  
    int id = g[to][back[to]].id;  
    int temp = dfs(min(flow,g[now][id].c),now);  
    g[now][id].c -= temp;  
    g[to][back[to]].c += temp;  
    return temp;  
}  
  
int ek()  
{  
    int ans = 0;  
    while(spfa())  
    {  
        ans+=dfs()*way[end];  
    }  
    return ans;  
}  
  
int main()  
{  
    while(cin>>n>>k)  
    {  
        v.clear();  
        vx.clear();  
        mx.clear();  
        for(int i=1;i<=n;i++)  
        {  
            cin>>x[i]>>y[i];  
            vx.pb(x[i]);  
            vx.pb(y[i]);  
        }  
        sort(vx.begin(),vx.end());  
        int temp=inf;  
        v.pb(-1);  
        for(int i=0;i<vx.size();i++)  
        {  
            if(vx[i]!=temp)  
            {  
                temp = vx[i];  
                v.pb(vx[i]);  
                v.pb(-1);  
            }  
        }  
        for(int i=1;i<v.size();i++)  
        {  
            mx[v[i]]=i;  
        }  
        for(int i=0;i<maxn;i++)  
        {  
            g[i].clear();  
        }  
        int cnt = v.size()-1;  
        for(int i=1;i<=cnt;i++)  
        {  
            link(i,i+add,k,0);  
        }  
        for(int i=1;i<cnt;i++)  
        {  
            link(i+add,i+1,k,0);  
        }  
        link(head,1,k,0);  
        link(cnt+add,end,k,0);  
        int now,to;  
        int ans=0;  
        for(int i=1;i<=n;i++)  
        {  
            now = mx[x[i]];  
            to = mx[y[i]];  
            now++;to--;  
            link(now,to+add,1,y[i]-x[i]);  
        }  
        cout<<ek()<<endl;  
    }  
    return 0;  
}  
22 最长k可重线段集问题 最大权不相交路径 最小费用最大流
23 火星探险问题 线性规划网络优化 最小费用最大流
24 骑士共存问题 二分图最大独立集 网络最小割

posted @ 2015-05-17 13:39  _tham  阅读(120)  评论(0编辑  收藏  举报