线性规划与网络流24题

来源:互联网 发布:阿里云远程连接不上 编辑:程序博客网 时间:2024/06/06 03:56

1.飞行员配对方案问题 二分匹配

#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int NN=110;int n,m,match[NN];bool mp[NN][NN],used[NN];bool dfs(int u){    for (int v=1; v<=m; v++) if (mp[u][v])    {        if (used[v]) continue;        used[v]=1;        if (match[v]==-1 || dfs(match[v]))        {            match[v]=u;            return true;        }    }    return false;}void hungary(){    memset(match,-1,sizeof(match));    int cnt=0;    for (int i=1; i<=n; i++)    {        memset(used,0,sizeof(used));        if (dfs(i)) cnt++;    }    if (cnt==0) puts("No Solution!");    else    {        printf("%d\n",cnt);        for (int i=1; i<=m; i++) if (match[i]!=-1)        {            printf("%d %d\n",match[i],i);        }    }}int main(){    int u,v;    scanf("%d%d",&n,&m);    memset(mp,0,sizeof(mp));    while (scanf("%d%d",&u,&v)==2 && u!=-1 && v!=-1)    {        mp[u][v]=1;    }    hungary();    return 0;}

2.太空飞行计划问题 最大权闭包

#include <cstdio>#include <vector>#include <cstring>#include <iostream>using namespace std;const int NN=888;const int MM=888888;const int INF=888888888;int S,T,NV,en,head[NN];struct Edge{    int u,v,f,next;    Edge() {}    Edge(int _u,int _v,int _f,int _next):u(_u),v(_v),f(_f),next(_next) {}} e[MM];void add(int u,int v,int f){    e[en]=Edge(u,v,f,head[u]);    head[u]=en++;    e[en]=Edge(v,u,0,head[v]);    head[v]=en++;}int gap[NN],dis[NN],cur[NN],pre[NN];int sap(){    int ret=0;    for (int i=0; i<NV; i++)    {        cur[i]=head[i];        dis[i]=gap[i]=0;    }    int aug=0;    int u=pre[S]=S;    gap[0]=NV;    while (dis[S]<NV)    {loop:        for (int &i=cur[u]; i!=-1; i=e[i].next)        {            int v=e[i].v;            if (e[i].f && dis[u]==dis[v]+1)            {                if (e[i].f<aug) aug=e[i].f;                pre[v]=u;                u=v;                if (u==T)                {                    ret+=aug;                    for (u=pre[u]; v!=S; v=u,u=pre[u])                    {                        e[cur[u]].f-=aug;                        e[cur[u]^1].f+=aug;                    }                    aug=INF;                }                goto loop;            }        }        int min_dis=NV;        for (int i=head[u]; i!=-1; i=e[i].next)        {            int v=e[i].v;            if (e[i].f>0 && dis[v]<min_dis)            {                min_dis=dis[v];                cur[u]=i;            }        }        if (--gap[dis[u]]==0) break;        gap[dis[u]=min_dis+1]++;        u=pre[u];    }    return ret;}bool f[NN];void dfs(int u){    f[u]=true;    for (int i=head[u]; i!=-1; i=e[i].next)    {        if (e[i].f && !f[e[i].v]) dfs(e[i].v);    }}vector<int> vec[NN];int main(){    int m,n,w,x;    char c;    en=0;    memset(head,-1,sizeof(head));    scanf("%d%d",&m,&n);    S=0;    T=m+n+1;    NV=T+1;    int sum=0;    for (int i=1; i<=m; i++)    {        scanf("%d",&w);        sum+=w;        add(S,i,w);        while (1)        {            while (c=getchar(),!isdigit(c) && c!='\n');            if (c=='\n') break;            x=c-'0';            c=getchar();            while (isdigit(c)) x=x*10+c-'0',c=getchar();            vec[i].push_back(x);            if (c=='\n') break;        }    }    for (int i=1; i<=n; i++)    {        scanf("%d",&w);        add(i+m,T,w);    }    for (int i=1; i<=m; i++)        for (int j=0; j!=vec[i].size(); j++) add(i,vec[i][j]+m,INF);    int ans=sum-sap();    memset(f,0,sizeof(f));    dfs(S);    bool flag=0;    for (int i=1; i<=m; i++) if (f[i])    {        if (!flag) flag=1;        else       printf(" ");        printf("%d",i);    }    puts("");    flag=0;    for (int i=1; i<=n; i++) if (f[i+m])    {        if (!flag) flag=1;        else       printf(" ");        printf("%d",i);    }    printf("\n%d\n",ans);    return 0;}
3.软件补丁问题 最短路dij

#include <cstdio>#include <queue>#include <cstring>#include <iostream>using namespace std;const int NN=110;const int MM=1100000;int n,m,w[NN],b1[NN],b2[NN],f1[NN],f2[NN];int dis[MM];bool vis[MM];struct node{    int v;    node () {}    node(int _v): v(_v) {}    bool operator <(const node a)const{        return dis[a.v]<dis[v];    }};bool match(int x,int i){    for (int j=0; j<n; j++)    {        if ( (b1[i]&(1<<j)) && !(x&(1<<j)) ) return 0;        if ( (b2[i]&(1<<j)) && (x&(1<<j)) ) return 0;    }    return 1;}int patch(int x,int i){    int y=x;    for (int j=0; j<n; j++)    {        if (f1[i]&(1<<j)) y|=1<<j;        if (f2[i]&(1<<j)) y&=~(1<<j);    }    return y;}priority_queue<node> q;int dij(){    memset(dis,0x7f,sizeof(dis));    memset(vis,0,sizeof(vis));    dis[(1<<n)-1]=0;    q.push(node((1<<n)-1));    while (!q.empty())    {        int u=q.top().v; q.pop();        if (u==0) return dis[u];        if (vis[u]) continue;        vis[u]=true;        //printf("%d %d\n",u,dis[u]);        for (int i=1; i<=m; i++) if (match(u,i))        {            int v=patch(u,i);//printf("v: %d,%d\n",v,i);            if (dis[v]>dis[u]+w[i])            {                dis[v]=dis[u]+w[i];                q.push(node(v));            }        }    }    return 0;}char s1[32],s2[32];int main(){    scanf("%d%d",&n,&m);    for (int i=1; i<=m; i++)    {        scanf("%d%s%s",&w[i],s1,s2);        b1[i]=b2[i]=0;        for (int j=0; j<n; j++)        {            if (s1[j]=='+') b1[i]|=1<<j;            if (s1[j]=='-') b2[i]|=1<<j;        }        f1[i]=f2[i]=0;        for (int j=0; j<n; j++)        {            if (s2[j]=='+') f1[i]|=1<<j;            if (s2[j]=='-') f2[i]|=1<<j;        }    }    printf("%d\n",dij());    return 0;}

待续。。。


原创粉丝点击