zoukankan      html  css  js  c++  java
  • UVA753:A Plug for UNIX

    题意:给定一些插座和一些插头,还有一些单向接头,比如A->B

    接头可以串联A->B->C->D

    使得插座和插头匹配数目最大

    题解:

    首先接头可以用Floyd处理

    这题可以转化为二分图的模型,就是直接连边,不做处理

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<map>
      6 #include<iostream>
      7 #include<algorithm>
      8 #include<string>
      9 #include<vector>
     10 #include<queue>
     11 #define MAXN 505
     12 #define INF 0x7f7f7f7f
     13 #define ll long long
     14 #define P 203
     15 using namespace std;
     16 int n,m,e,N;
     17 int V1[MAXN],V2[MAXN];
     18 int G[MAXN<<2][MAXN<<2];
     19 map<ll,int> mp;
     20 ll Hash(string s){
     21     ll ret=0;
     22     for(string::iterator it=s.begin();it!=s.end();it++){
     23         ret=ret*P+(*it);
     24     }
     25     return ret;
     26 }
     27 struct Edge{
     28     int from,to,cap,flow;
     29     Edge(int u=0,int v=0,int c=0,int f=0){
     30         from=u,to=v,cap=c,flow=f;
     31     }
     32 };
     33 struct Dinic{
     34     int n,m,s,t;
     35     vector<Edge> edges;
     36     vector<int> G[MAXN];
     37     int b[MAXN];
     38     int d[MAXN];
     39     int cur[MAXN];
     40     void init(int n,int s,int t){
     41         this->n=n;
     42         this->s=s,this->t=t;
     43         edges.clear();
     44         for(int i=0;i<=n;i++){
     45             G[i].clear();
     46         }
     47     }
     48     void AddEdge(int x,int y,int cap){
     49         edges.push_back(Edge(x,y,cap,0));
     50         edges.push_back(Edge(y,x,0,0));
     51         m=edges.size();
     52         G[x].push_back(m-2);
     53         G[y].push_back(m-1);
     54     }
     55     bool BFS(){
     56         memset(b,0,sizeof(b));
     57         queue<int> q;
     58         d[s]=0;
     59         q.push(s);
     60         b[s]=1;
     61         while(!q.empty()){
     62             int x=q.front();q.pop();
     63             for(int i=0;i<G[x].size();i++){
     64                 Edge& e=edges[G[x][i]];
     65                 if(e.cap>e.flow&&!b[e.to]){
     66                     d[e.to]=d[x]+1;
     67                     q.push(e.to);
     68                     b[e.to]=1;
     69                 }
     70             }
     71         }
     72         return b[t];
     73     }
     74     int dfs(int x,int a){
     75         if(x==t||!a)return a;
     76         int flow=0,f;
     77         for(int& i=cur[x];i<G[x].size();i++){
     78             Edge& e=edges[G[x][i]];
     79             if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
     80                 edges[G[x][i]].flow+=f;
     81                 edges[G[x][i]^1].flow-=f;
     82                 flow+=f;
     83                 a-=f;
     84                 if(!a){
     85                     break;
     86                 }
     87             }
     88         }
     89         return flow;
     90     }
     91     int Maxflow(){
     92         int flow=0;
     93         while(BFS()){
     94             memset(cur,0,sizeof(cur));
     95             flow+=dfs(s,INF);
     96         }
     97         return flow;
     98     }
     99 }D;
    100 void init(){
    101     memset(G,0,sizeof(G));
    102     mp.clear();
    103     N=0;
    104     ll h;
    105     string t1,t2;
    106     scanf("%d",&n);
    107     for(int i=1;i<=n;i++){
    108         cin>>t1;
    109         h=Hash(t1);
    110         if(mp.count(h)){
    111             V1[i]=mp[h];
    112         }
    113         else{
    114             N++;
    115             mp[h]=N;
    116             V1[i]=N;
    117         }
    118     }
    119     scanf("%d",&m);
    120     for(int i=1;i<=m;i++){
    121         cin>>t2>>t1;
    122         h=Hash(t1);
    123         if(mp.count(h)){
    124             V2[i]=mp[h];
    125         }
    126         else{
    127             N++;
    128             mp[h]=N;
    129             V2[i]=N;
    130         }
    131     }
    132     scanf("%d",&e);
    133     for(int i=1;i<=e;i++){
    134         cin>>t1>>t2;
    135         int c1,c2;
    136         h=Hash(t1);
    137         if(mp.count(h)){
    138             c1=mp[h];
    139         }
    140         else{
    141             N++;
    142             mp[h]=N;
    143             c1=N;            
    144         }
    145         h=Hash(t2);
    146         if(mp.count(h)){
    147             c2=mp[h];
    148         }
    149         else{
    150             N++;
    151             mp[h]=N;
    152             c2=N;            
    153         }
    154         G[c1][c2]=1;
    155     }
    156     for(int i=1;i<=n;i++){
    157         G[i][i]=1;    
    158     }
    159     for(int k=1;k<=N;k++){
    160         for(int i=1;i<=N;i++){
    161             for(int j=1;j<=N;j++){
    162                 G[i][j]|=(G[i][k]&G[k][j]);
    163             }
    164         }
    165     }
    166 }
    167 void solve(){
    168     D.init(n,0,n+m+1);
    169     for(int i=1;i<=m;i++){
    170         for(int j=1;j<=n;j++){
    171             if(G[V2[i]][V1[j]]){
    172                 D.AddEdge(i,j+m,1);
    173             }
    174         }    
    175     }
    176     for(int i=1;i<=m;i++){
    177         D.AddEdge(0,i,1);
    178     }
    179     for(int j=1;j<=n;j++){
    180         D.AddEdge(j+m,n+m+1,1);
    181     }
    182     printf("%d
    ",m-D.Maxflow());
    183 }
    184 int main()
    185 {
    186 //    freopen("data.in","r",stdin);
    187 //    freopen("my.out","w",stdout);
    188     int T;
    189     scanf("%d",&T);
    190     while(T--){
    191         init();
    192         solve();
    193         if(T){
    194             printf("
    ");
    195         }
    196     }
    197     return 0;
    198 }
    二分图匹配

    也可以把相同类型的压在一起处理,

    源点到某类型插头的容量就是该类型的数目,汇点同理

    如果相连的话建一条长度为INF的边,

    然后跑一遍最大流即可

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<map>
      6 #include<iostream>
      7 #include<algorithm>
      8 #include<string>
      9 #include<vector>
     10 #include<queue>
     11 #define MAXN 505
     12 #define INF 0x7f7f7f7f
     13 #define ll long long
     14 #define P 203
     15 using namespace std;
     16 int n,m,e,N;
     17 int V1[MAXN],V2[MAXN];
     18 int b1[MAXN],b2[MAXN];
     19 int cnt1,cnt2;
     20 int G[MAXN<<2][MAXN<<2];
     21 map<string,int> mp;
     22 struct Edge{
     23     int from,to,cap,flow;
     24     Edge(int u=0,int v=0,int c=0,int f=0){
     25         from=u,to=v,cap=c,flow=f;
     26     }
     27 };
     28 struct Dinic{
     29     int n,m,s,t;
     30     vector<Edge> edges;
     31     vector<int> G[MAXN];
     32     int b[MAXN];
     33     int d[MAXN];
     34     int cur[MAXN];
     35     void init(int n,int s,int t){
     36         this->n=n;
     37         this->s=s,this->t=t;
     38         edges.clear();
     39         for(int i=0;i<=n;i++){
     40             G[i].clear();
     41         }
     42     }
     43     void AddEdge(int x,int y,int cap){
     44         edges.push_back(Edge(x,y,cap,0));
     45         edges.push_back(Edge(y,x,0,0));
     46         m=edges.size();
     47         G[x].push_back(m-2);
     48         G[y].push_back(m-1);
     49     }
     50     bool BFS(){
     51         memset(b,0,sizeof(b));
     52         queue<int> q;
     53         d[s]=0;
     54         q.push(s);
     55         b[s]=1;
     56         while(!q.empty()){
     57             int x=q.front();q.pop();
     58             for(int i=0;i<G[x].size();i++){
     59                 Edge& e=edges[G[x][i]];
     60                 if(e.cap>e.flow&&!b[e.to]){
     61                     d[e.to]=d[x]+1;
     62                     q.push(e.to);
     63                     b[e.to]=1;
     64                 }
     65             }
     66         }
     67         return b[t];
     68     }
     69     int dfs(int x,int a){
     70         if(x==t||!a)return a;
     71         int flow=0,f;
     72         for(int& i=cur[x];i<G[x].size();i++){
     73             Edge& e=edges[G[x][i]];
     74             if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
     75                 edges[G[x][i]].flow+=f;
     76                 edges[G[x][i]^1].flow-=f;
     77                 flow+=f;
     78                 a-=f;
     79                 if(!a){
     80                     break;
     81                 }
     82             }
     83         }
     84         return flow;
     85     }
     86     int Maxflow(){
     87         int flow=0;
     88         while(BFS()){
     89             memset(cur,0,sizeof(cur));
     90             flow+=dfs(s,INF);
     91         }
     92         return flow;
     93     }
     94 }D;
     95 void init(){
     96     memset(G,0,sizeof(G));
     97     memset(b1,0,sizeof(b1));
     98     memset(b2,0,sizeof(b2));
     99     cnt1=cnt2=0;
    100     mp.clear();
    101     N=0;
    102     string t1,t2;
    103     scanf("%d",&n);
    104     for(int i=1;i<=n;i++){
    105         cin>>t1;
    106         if(mp.count(t1)){
    107             V1[i]=mp[t1];
    108         }
    109         else{
    110             N++;
    111             mp[t1]=N;
    112             V1[i]=N;
    113         }
    114     }
    115     scanf("%d",&m);
    116     for(int i=1;i<=m;i++){
    117         cin>>t2>>t1;
    118         if(mp.count(t1)){
    119             V2[i]=mp[t1];
    120         }
    121         else{
    122             N++;
    123             mp[t1]=N;
    124             V2[i]=N;
    125         }
    126     }
    127     scanf("%d",&e);
    128     for(int i=1;i<=e;i++){
    129         cin>>t1>>t2;
    130         int c1,c2;
    131         if(mp.count(t1)){
    132             c1=mp[t1];
    133         }
    134         else{
    135             N++;
    136             mp[t1]=N;
    137             c1=N;            
    138         }
    139         if(mp.count(t2)){
    140             c2=mp[t2];
    141         }
    142         else{
    143             N++;
    144             mp[t2]=N;
    145             c2=N;            
    146         }
    147         G[c1][c2]=1;
    148     }
    149     for(int i=1;i<=n;i++){
    150         G[i][i]=1;    
    151     }
    152     for(int k=1;k<=N;k++){
    153         for(int i=1;i<=N;i++){
    154             for(int j=1;j<=N;j++){
    155                 G[i][j]|=(G[i][k]&G[k][j]);
    156             }
    157         }
    158     }
    159     for(int i=1;i<=n;i++){
    160         if(!b1[V1[i]]){
    161             cnt1++;
    162         }
    163         b1[V1[i]]++;
    164     }
    165     for(int i=1;i<=m;i++){
    166         if(!b2[V2[i]]){
    167             cnt2++;
    168         }
    169         b2[V2[i]]++;
    170     }
    171 }
    172 void solve(){
    173     D.init(n,0,cnt1+cnt2+1);
    174     int t1=0,t2=cnt1;
    175     for(int i=1;i<=N;i++){
    176         if(b2[i]) t2++;
    177         else continue;
    178         t1=0;
    179         for(int j=1;j<=N;j++){
    180             if(b1[j]){
    181                 t1++;
    182                 if(G[i][j]){
    183                     D.AddEdge(t1,t2,INF);
    184                 }
    185             }
    186         }
    187     }
    188     t1=0;
    189     for(int i=1;i<=N;i++){
    190         if(b1[i]){
    191             t1++;
    192             D.AddEdge(0,t1,b1[i]);
    193         }
    194     }
    195     t2=0;
    196     for(int j=1;j<=N;j++){
    197         if(b2[j]){
    198             t2++;
    199             D.AddEdge(t2+cnt1,cnt1+cnt2+1,b2[j]);
    200         }
    201     }
    202     printf("%d
    ",m-D.Maxflow());
    203 }
    204 int main()
    205 {
    206 //    freopen("data.in","r",stdin);
    207 //    freopen("my.out","w",stdout);
    208     int T;
    209     scanf("%d",&T);
    210     while(T--){
    211         init();
    212         solve();
    213         if(T){
    214             printf("
    ");
    215         }
    216     }
    217     return 0;
    218 }
    压点最大流
  • 相关阅读:
    java+opencv实现图像灰度化
    java实现高斯平滑
    hdu 3415 单调队列
    POJ 3368 Frequent values 线段树区间合并
    UVA 11795 Mega Man's Mission 状态DP
    UVA 11552 Fewest Flops DP
    UVA 10534 Wavio Sequence DP LIS
    UVA 1424 uvalive 4256 Salesmen 简单DP
    UVA 1099 uvalive 4794 Sharing Chocolate 状态DP
    UVA 1169uvalive 3983 Robotruck 单调队列优化DP
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7842493.html
Copyright © 2011-2022 走看看