zoukankan      html  css  js  c++  java
  • [bzoj1562][NOI2009]变换序列

    题目大意:有两个序列$a$和$b$,每个分别有$n(nleqslant10^4)$个元素,序列$a$中的数为$0sim n-1$的一个排列。$T_i$为$(a_i+b_i)mod n$或者$(a_i-b_i)mod n$。要求使得$displaystyleigcuplimits_{i=1}^{n-1}T_i={0,1,cdots,n-1}$,输出$T_i$,如有多解,输出字典序最小的

    题解:匈牙利算法,二分图完美匹配,每个$T_i$都有两种取值,可以倒着搜索,使得数字小的可以把数字大的挤掉,并且在枚举边的时候,从小到大搜索,就可以保证字典序最小,复杂度$O(n^2)$

    卡点:1.最后 puts("") 锅了。。。。



    C++ Code:

    #include <cstdio>
    #include <cstring>
    #include <bitset>
    #define maxn 10010
    int n, ans[maxn], res[maxn];
    int e[maxn][2];
    std::bitset<maxn> v;
    bool dfs(int x) {
    	for (int i = 0; i < 2; i++) {
    		if (!v[e[x][i]]) {
    			v.set(e[x][i]);
    			if (!~res[e[x][i]] || dfs(res[e[x][i]])) {
    				res[e[x][i]] = x;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    inline void swap(int &a, int &b) {a ^= b ^= a ^= b;}
    int main() {
    	scanf("%d", &n);
    	for (int i = 0; i < n; i++) {
    		int a;
    		scanf("%d", &a);
    		e[i][0] = (i + a) % n;
    		e[i][1] = (i + n - a) % n;
    		if (e[i][0] > e[i][1]) swap(e[i][0], e[i][1]);
    	}
    	memset(res, -1, sizeof res);
    	int tmp = n;
    	for (int i = n - 1; ~i; i--) {
    		v.reset();
    		if (dfs(i)) tmp--;
    	}
    	if (tmp) {
    		puts("No Answer");
    		return 0;
    	}
    	for (int i = 0; i < n; i++) ans[res[i]] = i;
    	for (int i = 0; i < n; i++) printf("%d ", ans[i]);
    	puts("");
    	return 0;
    }
    
  • 相关阅读:
    MySQL语句创建表、插入数据遇到的问题-20/4/18
    【Navicat】MySQL 8.0.17 数据库报2059错误
    MySQL 8.0.17 版安装 || Windows
    C#--Invoke和BeginInvoke用法和区别
    C#--params关键字
    C#--typeof() 和 GetType()区别
    C#--利用反射编写的SqlHelper类
    C#--反射基础
    C#--LINQ--2--LINQ高级查询
    C#--LINQ--1--初学LINQ基础和查询
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9582992.html
Copyright © 2011-2022 走看看