zoukankan      html  css  js  c++  java
  • HDU4687 Boke and Tsukkomi

    题目链接:https://vjudge.net/problem/HDU-4687

    知识点:  带花树开花算法

    解题思路:

      先求出原来的一般图的最大匹配数(iCnt). 然后枚举每一个组合,尝试去掉图中所有以这个组合中任意一点为端点的边,求出此时的最大匹配数(tCnt),如果(tCnt<iCnt-1),则这个组合对于任意一种最大匹配来说都是多余的。

    AC代码:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef pair<int,int> P ;
      4 const int maxn = 40+5, maxm = 150;
      5 int N,M;
      6 bool Graph[maxn][maxn],G[maxn][maxn];
      7 int Match[maxn];
      8 bool InQueue[maxn],InPath[maxn],InBlossom[maxn];
      9 int Head,Tail;
     10 int Queue[maxn];
     11 int Start,Finish;
     12 int NewBase;
     13 int Father[maxn],Base[maxn];
     14 
     15 P inp[maxm];
     16 
     17 void Push(int u){
     18     Queue[Tail]=u;
     19     Tail++;
     20     InQueue[u]=true;
     21 }
     22 int Pop(){
     23     int res=Queue[Head];
     24     Head++;
     25     return res;
     26 }
     27 int FindCommonAncestor(int u,int v){
     28     memset(InPath,false,sizeof(InPath));
     29     while(1){
     30         u=Base[u];
     31         InPath[u]=true;
     32         if(u==Start)    break;
     33         u=Father[Match[u]];
     34     }
     35     while(1){
     36         v=Base[v];
     37         if(InPath[v])   break;
     38         v=Father[Match[v]];
     39     }
     40     return v;
     41 }
     42 void ResetTrace(int u){
     43     int v;
     44     while(Base[u]!=NewBase){
     45         v=Match[u];
     46         InBlossom[Base[u]]=InBlossom[Base[v]]=true;
     47         u=Father[v];
     48         if(Base[u]!=NewBase)    Father[u]=v;
     49     }
     50 }
     51 void BloosomContract(int u,int v){
     52     NewBase = FindCommonAncestor(u,v);
     53     memset(InBlossom,false,sizeof(InBlossom));
     54     ResetTrace(u);  ResetTrace(v);
     55     if(Base[u]!=NewBase)    Father[u]=v;
     56     if(Base[v]!=NewBase)    Father[v]=u;
     57     for(int tu=1;tu<=N;tu++){
     58         if(InBlossom[Base[tu]]){
     59             Base[tu]=NewBase;
     60             if(!InQueue[tu])    Push(tu);
     61         }
     62     }
     63 }
     64 void FindAugmentingPath(){
     65     memset(InQueue,false,sizeof(InQueue));
     66     memset(Father,0,sizeof(Father));
     67     for(int i=1;i<=N;i++)   Base[i]=i;
     68     Head=Tail=1;
     69     Push(Start);
     70     Finish=0;
     71     while(Head<Tail){
     72         int u=Pop();
     73         for(int v=1;v<=N;v++){
     74             if(Graph[u][v]&&(Base[u]!=Base[v])&&(Match[u]!=v)){
     75                 if((v==Start)||(Match[v]>0)&&(Father[Match[v]]>0))
     76                     BloosomContract(u,v);
     77                 else if(Father[v]==0){
     78                     Father[v]=u;
     79                     if(Match[v]>0)  Push(Match[v]);
     80                     else{
     81                         Finish=v;
     82                         return;
     83                     }
     84                 }
     85             }
     86         }
     87     }
     88 }
     89 void AugumentPath(){
     90     int u,v,w;
     91     u=Finish;
     92     while(u>0){
     93         v=Father[u];
     94         w=Match[v];
     95         Match[v]=u;
     96         Match[u]=v;
     97         u=w;
     98     }
     99 }
    100 void Edmonds(){
    101     memset(Match,0,sizeof(Match));
    102     for(int u=1;u<=N;u++){
    103         if(Match[u]==0){
    104             Start =u;
    105             FindAugmentingPath();
    106             if(Finish>0)    AugumentPath();
    107         }
    108     }
    109 }
    110 
    111 int main(){
    112     int u,v;
    113     while(scanf("%d%d",&N,&M)==2){
    114         memset(G,false,sizeof(G));
    115         memset(Graph,false,sizeof(Graph));
    116         for(int i=1;i<=M;i++){
    117             scanf("%d%d",&u,&v);
    118             inp[i]=make_pair(u,v);
    119             Graph[u][v]=Graph[v][u]=G[u][v]=G[v][u]=true;
    120         }
    121         Edmonds();
    122         int iCount=0;
    123         for(int u=1;u<=N;u++){
    124             if(Match[u]>0)  iCount++;
    125         }iCount/=2;
    126         vector<int> ans;
    127         for(int i=1;i<=M;i++){
    128             int u=inp[i].first,v=inp[i].second;
    129             for(int j=1;j<=N;j++)   Graph[u][j]=Graph[j][u]=Graph[v][j]=Graph[j][v]=false;
    130             Edmonds();
    131             int tCount=0;
    132             for(int u=1;u<=N;u++){
    133                 if(Match[u]>0)  tCount++;
    134             }tCount/=2;
    135             if(tCount<iCount-1) ans.push_back(i);
    136             for(int j=1;j<=N;j++){
    137                 Graph[u][j]=G[u][j];
    138                 Graph[j][u]=G[j][u];
    139                 Graph[v][j]=G[v][j];
    140                 Graph[j][v]=G[j][v];
    141             }
    142         }
    143         int sz=ans.size();
    144         printf("%d
    ",sz);
    145         for(int i=0;i<sz;i++){
    146             if(i!=0)    printf(" ");
    147             printf("%d",ans[i]);
    148         }
    149         printf("
    ");
    150     }
    151     return 0;
    152 }

      

    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    调用tensorflow中的concat方法时Expected int32, got list containing Tensors of type '_Message' instead.
    lstm公式推导
    RNN推导
    word2vec原理
    反向传播神经网络入门
    mac升级系统自带numpy失败解决方案
    mac安装.net core
    mac 当前位置打开终端
    docker安装配置
    KVM性能优化学习笔记
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/8414271.html
Copyright © 2011-2022 走看看