好长时间没更博客了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! */