洛谷 p2055 假期的宿舍 題解

好長時間沒更博客了c++

由於實在太蒻了算法

這讓本蒟蒻怎麼辦spa

今天終於遇到了一道模板題(以前也有,不過太蒻了都不會)debug

不過...寫代碼5分鐘,調試2小時調試


分界線:迴歸正題code

這個就是普通的匈牙利算法 差很少blog

思路:

咱們須要統計出誰須要牀,誰有牀get

咱們的二分圖就是 須要的人博客

跑匈牙利就行了it

什麼人不須要牀?? 在校且回家的人

什麼牀能用?? 在校的人

因爲人的序號和牀的序號會重複

因此我在牀的序號上加了m,(好比一共有3我的,一號牀的"名字"就是4)

若是還不明白上面那句那就能夠理解爲#define 一號牀 4

因爲題目要求輸入是鄰接矩陣,因此咱們能夠只讀入一半(左上角和右下角連線以左不讀)
由於人的信任是相互的

對應好以後就能夠了

作這道題,怎麼作?

1 : 學會匈牙利算法,無論你用Google.Baidu.360.搜狗.bing.yandex......什麼引擎(能用就行)
都有很生動的例子,這裏再也不贅述

2 : 學會圖論基本知識,會用鄰接表存邊(只會鄰接矩陣的話能夠先學一學或者看懂個人以後本身寫)

3 : 寫代碼,就是用你的小爪爪摸一下鍵盤

4 : debug,dalao自行跳過

5 : 最重要的一步:

打上神獸!!!!

┌─┐        ┌─┐
   ┌─┘  ┴────┘  ┴─┐
   │                        │
   │         ───         │
   │  ─┬┘        └┬─  │
   │                        │
   │         ─┴─         │
   │                        │
   └──┐            ┌──┘
         │            │
         │            │
         │            │
         │            │
         │            │
         │            │
         │            │
         │            └──────────┐
         │                                  │
         │                                  ├─┐
         │                                  ┌─┘
         │                                  │
         └─┐  ┐  ┌────┬  ┐  ┌──┘
             │─┤─┤        │─┤─┤
             └─┴─┘        └─┴─┘
                           神獸保佑
                         代碼無BUG!

看起來好像不大對,可是粘貼到記事本或sublime(Dev也行)

就會變成很是帥氣的樣子

如今貼代碼

#include<bits/stdc++.h>

using namespace std;

inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}
inline void write(int x) {if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); }

int u[10001],v[10001],f[10001],N[10001],g[10001];
bool bj[10001],bj2[10001],book[10001];

void add(int x,int y,int z){//鄰接表存邊
    u[z] = x; v[z] = y;

    N[z] = f[x]; f[x] = z;
}

bool find(int x){//匈牙利模板
    for(int i = f[x];i != -1;i = N[i]){
        int p = v[i];
        if(!book[p]){
            book[p] = 1;
            if(g[p] == 0 || find(g[p])){
                g[p] = x;
                return 1;
            }
        }
    }
    return 0;
}

int main(int argc, char const *argv[])
{
    int yy;
    yy = read();

    while(yy){
        int tt = 0;
        yy--;
        memset(f,-1,sizeof f);//多測不清空,爆零兩行淚
        memset(u,0,sizeof u);
        memset(v,0,sizeof v);
        memset(g,0,sizeof g);
        memset(bj,0,sizeof bj);
        memset(bj2,0,sizeof bj2);

        int m,x,tot = 0;
        m = read();

        for(int i = 1;i <= m;++i) bj[i] = read();//在校標記
        
        for(int i = 1;i <= m;++i) {
            x = read();
            bj2[i] = x;//是否回家的標記
            
            if(!bj[i]) bj2[i] = 0;//不在校就能夠當不回家處理(由於須要牀)
            if(bj2[i]) tt++;
        }

        for(int i = 1;i <= m;++i){
            for(int j = 1;j <= m;++j){
                x = read();
                if(i > j) continue;//只讀一半

                if(i == j && bj[i])//本身能夠睡本身的牀
                    x = 1;
                if(x == 0) continue;//不能互相睡牀不存邊
                
                if(bj[j] && !bj2[i]){//j有牀i不回家就加邊
        //          cout<<i<<" "<<j<<endl;
                    add(i,m + j,++tot);
                }
                
                if(i == j) continue;
                
                if(bj[i] && !bj2[j]){//同理
        //          cout<<j<<" "<<i<<endl;
                    add(j,m + i,++tot);
                }
            }
        }

        // for(int i = 1;i <= m;++i){
        //  cout<<f[i]<<" "<<N[i]<<endl;
        // }

        int cnt = 0;
        for(int i = 1;i <= m;++i){
            memset(book,0,sizeof book);
            if(find(i)) cnt++;
        }
        
        if(cnt == m - tt) cout<<"^_^"<<"\n";
        else cout<<"T_T"<<"\n";
    }
    return 0;
}

/***
  *        ┌─┐        ┌─┐
  *    ┌─┘  ┴────┘  ┴─┐
  *    │                        │
  *    │         ───         │
  *    │  ─┬┘        └┬─  │
  *    │                        │
  *    │         ─┴─         │
  *    │                        │
  *    └──┐            ┌──┘
  *          │            │
  *          │            │
  *          │            │
  *          │            │
  *          │            │
  *          │            │
  *          │            │
  *          │            └──────────┐
  *          │                                  │
  *          │                                  ├─┐
  *          │                                  ┌─┘
  *          │                                  │
  *          └─┐  ┐  ┌────┬  ┐  ┌──┘
  *              │─┤─┤        │─┤─┤
  *              └─┴─┘        └─┴─┘
  *                            神獸保佑
  *                          代碼無BUG!
  */
相關文章
相關標籤/搜索