好長時間沒更博客了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! */