zoukankan      html  css  js  c++  java
  • 【PowerOJ1742&网络流24题】试题库问题(最大流)

    题意:

     思路:

    【问题分析】

    二分图多重匹配问题,用最大流解决。

    【建模方法】

    建立二分图,每个类别为X集合中的顶点,每个题为Y集合中的顶点,增设附加源S和汇T。

    1、从S向每个Xi连接一条容量为该类别所需数量的有向边。

    2、从每个Yi向T连接一条容量为1的有向边。

    3、如果一个题i属于一个类别j,连接一条从Xj到Yi容量为1的有向边。

    求网络最大流,如果最大流量等于所有类别所需之和,则存在解,否则无解。对于每个类别,从X集合对应点出发的所有满流边,指向的B集合中的顶点就是该类别的所选的题(一个可行解)。

    【建模分析】

    二分图多重匹配问题。X,Y集合之间的边容量全部是1,保证两个点只能匹配一次,源汇的连边限制了每个点匹配的个数。求出网络最大流,如果流量等于X集合所有点与S边容量之和,那么则说明X集合

    每个点都有完备的多重匹配。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef unsigned int uint;
      5 typedef unsigned long long ull;
      6 typedef long double ld;
      7 typedef pair<int,int> PII;
      8 typedef pair<ll,ll> Pll;
      9 typedef vector<int> VI;
     10 typedef vector<PII> VII;
     11 typedef pair<ll,ll>P;
     12 #define N  100010
     13 #define M  1000000
     14 #define INF 1e9
     15 #define fi first
     16 #define se second
     17 #define MP make_pair
     18 #define pb push_back
     19 #define pi acos(-1)
     20 #define mem(a,b) memset(a,b,sizeof(a))
     21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
     22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
     23 #define lowbit(x) x&(-x)
     24 #define Rand (rand()*(1<<16)+rand())
     25 #define id(x) ((x)<=B?(x):m-n/(x)+1)
     26 #define ls p<<1
     27 #define rs p<<1|1
     28 
     29 const ll MOD=1e9+7,inv2=(MOD+1)/2;
     30       double eps=1e-6;
     31       int dx[4]={-1,1,0,0};
     32       int dy[4]={0,0,-1,1};
     33 
     34 VI c[N];
     35 int head[N],vet[N],len[N],nxt[N],a[N],dis[N],s,S,T,tot;
     36 
     37 int read()
     38 {
     39    int v=0,f=1;
     40    char c=getchar();
     41    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     42    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     43    return v*f;
     44 }
     45 
     46 void add(int a,int b,int c)
     47 {
     48     nxt[++tot]=head[a];
     49     vet[tot]=b;
     50     len[tot]=c;
     51     head[a]=tot;
     52 
     53     nxt[++tot]=head[b];
     54     vet[tot]=a;
     55     len[tot]=0;
     56     head[b]=tot;
     57 }
     58 
     59 bool bfs()
     60 {
     61     queue<int>q;
     62     rep(i,1,s) dis[i]=-1;
     63     q.push(S),dis[S]=0;
     64     while(!q.empty())
     65     {
     66         int u=q.front();
     67         q.pop();
     68         int e=head[u];
     69         while(e)
     70         {
     71             int v=vet[e];
     72             if(len[e]&&dis[v]==-1)
     73             {
     74                 dis[v]=dis[u]+1;
     75                 q.push(v);
     76             }
     77             e=nxt[e];
     78         }
     79     }
     80     return dis[T]!=-1;
     81 }
     82 
     83 int dfs(int u,int aug)
     84 {
     85     if(u==T) return aug;
     86     int e=head[u],val=0,flow=0;
     87     while(e)
     88     {
     89         int v=vet[e];
     90         if(len[e]&&dis[v]==dis[u]+1)
     91         {
     92             int t=dfs(v,min(len[e],aug));
     93             if(!t)
     94             {
     95                 e=nxt[e];
     96                 continue;
     97             }
     98             flow+=t;
     99             aug-=t;
    100             len[e]-=t;
    101             len[e^1]+=t;
    102             if(!aug) break;
    103         }
    104         e=nxt[e];
    105     }
    106     if(!flow) dis[u]=-1;
    107     return flow;
    108 }
    109 
    110 int maxflow()
    111 {
    112     int res=0;
    113     while(bfs()) res+=dfs(S,INF);
    114     return res;
    115 }
    116 
    117 int main()
    118 {
    119     //freopen("1.in","r",stdin);
    120     //freopen("1.out","w",stdout);
    121     int K=read(),n=read();
    122     s=K+n;
    123     S=++s,T=++s;
    124     rep(i,1,K)
    125     {
    126         a[i]=read();
    127         add(i+n,T,a[i]);
    128     }
    129     rep(i,1,n)
    130     {
    131         int x=read();
    132         add(S,i,1);
    133         rep(j,1,x)
    134         {
    135             int y=read();
    136             add(i,y+n,1);
    137         }
    138     }
    139     int sum=0;
    140     rep(i,1,n) sum+=a[i];
    141     int flow=maxflow();
    142     //printf("sum=%d flow=%d
    ",sum,flow);
    143     if(sum!=flow) printf("No Solution!
    ");
    144      else
    145      {
    146         rep(i,1,n)
    147         {
    148             int e=head[i];
    149             while(e)
    150             {
    151                 int v=vet[e];
    152                 if(len[e]&&c[v-n].size()<a[v-n])
    153                 {
    154                     c[v-n].pb(i);
    155                     break;
    156                 }
    157                 e=nxt[e];
    158             }
    159         }
    160         rep(i,1,K)
    161         {
    162             printf("%d: ",i);
    163             for(int j=0;j<c[i].size();j++) printf("%d ",c[i][j]);
    164             printf("
    ");
    165         }
    166      }
    167     return 0;
    168 }
  • 相关阅读:
    PHP基础入门(五)---PHP面向对象实用基础知识
    PHP基础入门(四)---PHP数组实用基础知识
    PHP基础入门(三)---PHP函数基础
    PHP基础入门(二)---入门基础知识必备
    PHP基础入门(一)---世界上最好用的编程语言
    【JavaScript OPP基础】---新手必备
    高级软件工程第六次作业:“希希敬敬对”团队作业-3
    高级软件工程第五次作业:“希希敬敬对”团队作业-2
    第四次软件工程团队作业:“希希敬敬对”队团队展示
    高级软件工程第三次作业:数独游戏界面功能
  • 原文地址:https://www.cnblogs.com/myx12345/p/11758950.html
Copyright © 2011-2022 走看看