• UOJ 171 【WC2016】挑战NPC


      一开始还真没想到是一般图匹配这种模型(毕竟才会的带花树)

      把每一个盒子拆成3个,每一个可以放置进它的小球分别向这三个点连边,然后这三个点在连成一个三元环,最终答案就是小球数目-匹配数。

      由于是一般图,所以套一个带花树就可以了。

      

      NOTICE:寻找增广路时,应该从球先找起,这样子才保证了每个球有地方放置。

      


      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<vector>
      5 #include<cstdlib>
      6 #include<cmath>
      7 #include<cstring>
      8 using namespace std;
      9 #define maxn 10010
     10 #define llg long long 
     11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
     12 llg n,m,sett,father[maxn],pre[maxn],match[maxn],vis[maxn],id[maxn],dl[maxn*10],head,tail,ans,T,totn,e;
     13 llg c[1000][1000];
     14 
     15 vector<llg> a[maxn];
     16 
     17 llg find(llg x){if (father[x]!=x) father[x]=find(father[x]); return father[x];}
     18 
     19 llg lca(llg x,llg y)
     20 {
     21     sett++;
     22     while (vis[x]!=sett)
     23     {
     24         if (x)
     25         {
     26             x=find(x);
     27             if (vis[x]==sett) return x;
     28             vis[x]=sett;
     29             if (match[x]!=0) x=find(pre[match[x]]);
     30             else x=0;
     31         }
     32         
     33             swap(x,y);
     34     }
     35     return x;
     36 }
     37 
     38 void change(llg x,llg y,llg fa)
     39 {
     40     llg z;
     41     while (find(x)!=fa)
     42     {
     43         pre[x]=y; z=match[x];
     44         if (id[z]==1) {id[z]=0,dl[++tail]=z;}
     45         if (find(z)==z) father[z]=fa;
     46         if (find(x)==x) father[x]=fa;
     47         y=z; x=pre[y];
     48     }
     49 }
     50 
     51 bool bfs(llg p)
     52 {
     53     llg x,w,v;
     54     for (llg i=1;i<=n;i++) id[i]=-1,father[i]=i;
     55     head=0,tail=1,dl[1]=p; id[p]=0;
     56     do
     57     {
     58         x=dl[++head],w=a[x].size();
     59         for (llg i=0;i<w;i++)
     60         {
     61             v=a[x][i];
     62             if (id[v]==-1)
     63             {
     64                 pre[v]=x;
     65                 id[v]=1;
     66                 if (!match[v])
     67                 {
     68                     llg last,t,now=v;
     69                     while (now!=0)
     70                     {
     71                         t=pre[now],last=match[t];
     72                         match[t]=now; match[now]=t;
     73                         now=last;// v=t;
     74                     }//把原lai的匹配和非匹配bian取反
     75                     return 1;
     76                 }
     77                 id[match[v]]=0,dl[++tail]=match[v];
     78             }
     79             else
     80                 if (id[v]==0 && find(v)!=find(x))
     81                 {
     82                     llg dad=lca(x,v);
     83                     change(x,v,dad);
     84                     change(v,x,dad);
     85                 }
     86         }
     87     }while (head!=tail);
     88     return 0;
     89 
     90 }
     91 
     92 void link(llg x,llg y) {a[x].push_back(y),a[y].push_back(x);}
     93 
     94 void init()
     95 {
     96     for (llg i=1;i<=n;i++) a[i].clear(),vis[i]=match[i]=pre[i]=father[i]=id[i]=dl[i]=0;
     97     //for (llg i=1;i<=n;i++) for (llg j=1;j<=n;j++) c[i][j]=c[j][i]=0;
     98     scanf("%lld%lld%lld",&n,&m,&e);
     99     totn=n;
    100     llg x,y;
    101     for (llg i=1;i<=e;i++)
    102     {
    103         scanf("%lld%lld",&x,&y);
    104         
    105         llg po=m*3+x;
    106         link(po,y*3-2),link(po,y*3-1),link(po,y*3);
    107         //a[x].push_back(y),a[y].push_back(x);
    108     }
    109     n=n+m*3;
    110     for (llg i=1;i<=m;i++)
    111     {
    112         link(i*3-2,i*3-1),link(i*3-1,i*3),link(i*3,i*3-2);
    113     }
    114 }
    115 
    116 void oupt()
    117 {
    118     cout<<ans-totn<<endl;
    119     for (llg i=1;i<=totn;i++)
    120     {
    121         printf("%lld ",(match[3*m+i]-1)/3+1);
    122     }
    123     printf("
    ");
    124 }
    125 
    126 int main()
    127 {
    128     //yyj("a");
    129     cin>>T;
    130     while (T--)
    131     {
    132         ans=0;
    133         init();
    134         for (llg i=n;i>1;i--) 
    135             if (!match[i] && bfs(i)) ans++;
    136         oupt();
    137     }    
    138     return 0;
    139 }
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    时间模块(二)datetime
    xmltodict模块
    C和指针
    C和指针指针
    笔试2
    istream_iterator,ostream_iterator与vector的转换
    C++工厂方法与反射的简单实现
    rpcndr.h和wtypes.h冲突Bug的解决方案
    ubuntu 9.04 安装mysql
    QT in Ubuntu cannot find lfreetype
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6270550.html
Copyright © 2020-2023  润新知