• [洛谷P1129][ZJOI2007]矩阵游戏


    题目大意:矩阵游戏在一个$N imes N$的方阵进行。每次可以交换矩阵任意两行或两列,要求若干次操作后使得主对角线上的元素均为$1$。判断是否有解

    题解:观察题目,可以发现是一个二分图匹配问题,即要求把行和列进行匹配,一个$1$就是一条边,若最大匹配为$n$就有解,否则无解

    卡点:1.最开始题意理解错

     

    C++ Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn = 410;
    const int inf = 0x3f3f3f3f;
    int Tim, n, a;
    int d[maxn], q[maxn], h, t;
    int st, ed;
    int head[maxn], cnt = 2, head_[maxn];
    struct Edge {
    	int to, nxt, w;
    } e[210 * 210 << 1];
    void add(int a, int b, int c) {
    	e[cnt] = (Edge) {b, head[a], c}; head[a] = cnt;
    	e[cnt ^ 1] = (Edge) {a, head[b], 0}; head[b] = cnt ^ 1;
    	cnt += 2;
    }
    inline int min(int a, int b) {if (a < b) return a; else return b;}
    inline bool bfs() {
    	memset(d, 0, sizeof d);
    	memcpy(head, head_, sizeof head_);
    	d[q[h = t = 0] = st] = 1;
    	int u, v;
    	while (h <= t) {
    		u = q[h++];
    		if (u == ed) return true;
    		for (register int i = head[u]; i; i = e[i].nxt) {
    			v = e[i].to;
    			if (!d[v] && e[i].w) {
    				d[v] = d[u] + 1;
    				q[++t] = v;
    			}
    		}
    	}
    	return d[ed];
    }
    inline int dfs(int x, int low) {
    	if (x == ed || !low) return low;
    	int res = 0, w, v;
    	for (register int &i = head[x]; i; i = e[i].nxt) {
    		v = e[i].to;
    		if (d[x] + 1 == d[v] && e[i].w) {
    			w = dfs(v, min(low - res, e[i].w));
    			e[i].w -= w;
    			e[i ^ 1].w += w;
    			res += w;
    			if (res == low) return res;
    		}
    	}
    	if (!res) d[x] = -1;
    	return res;
    }
    int dinic(int n) {
    	int ans = 0;
    	memcpy(head_, head, sizeof head_);
    	while (bfs()) ans += dfs(st, inf);
    	if (ans == n) puts("Yes");
    	else puts("No");
    }
    int main() {
    	scanf("%d", &Tim);
    	while (Tim--) {
    		scanf("%d", &n);
    		st = 0, ed = n << 1 | 1;
    		for (int i = 1; i <= n; i++) {
    			add(st, i, 1);
    			add(i + n, ed, 1);
    			for (int  j = 1; j <= n; j++) {
    				scanf("%d", &a);
    				if (a) {
    					add(i, j + n, 1);
    				}
    			}
    		}
    		dinic(n);
    		if (Tim) {
    			memset(head, 0, sizeof head);
    			cnt = 2;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    SQL语句实例学习汇总
    sql语句一些实用技巧for oracle
    无限级递归生成HTML示例及ListBox,DropDownList等无限树
    另类Sql语句直接导出表数据到Execl
    powerdesigner中sql脚本小写转大写,去双引号
    C#中利用jQuery获取Json值示例,Ajax方式。
    利用jquery解决下拉菜单被Div遮挡问题
    获取Textarea 元素当前的光标位置及document.selection.createRange()资料
    oracle中一些常用函数
    IE6 动态创建 iframe 无法显示的 bug,万恶的IE6
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9395192.html
Copyright © 2020-2023  润新知