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 }
    压点最大流
  • 相关阅读:
    7、cad图纸打印
    对账
    练习10—去掉图片文字
    6、cad里面如何快速将图纸的线条全部变成黑色
    5、cad如何快速选中图纸上所有文字
    4、如何修改cad的背景色为白色
    练习九—快速修饰面部光影
    iOS alloc&init探索
    export default / export const
    Vue2.0+组件库总结
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7842493.html
Copyright © 2011-2022 走看看