CodeFroces NWERC 2015 E.Elementary Math(二分图)

题意:给出n对数字,可以在n对数字中间用+,-,*三种运算,要保证最后得到的答案不能有相同的。

解法:考虑到n只有2500,数据量比较小,最多只会有7500种结果,所以可以构造二分图。左边是n个点代表n对数字,右边?个点,代表结果。左边n个数字都向着右边他所能得到的答案连一条边。

如果有两对数字运算结果相同,那么他们同时连到这个点上面。

看看最后最大匹配是否等于n就知道可不可行了。

复杂度是O(VE),E = 3 * V,所以就是O(3 * V²)。

代码如下:(62ms)

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<utility>
#include<stack>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<map>
using namespace std;

const int maxn = 2505;
int uN, vN;  //u,v数目
int G[maxn][maxn * 3];//编号是0~n-1的 
int linker[maxn * 3];
int linker2[maxn];
bool used[maxn * 3];
bool dfs(int u)
{
    int v;
    for(v = 0; v < vN; v++)
        if(G[u][v] && !used[v])
        {
            used[v] = true;
            if(linker[v] == -1 || dfs(linker[v]))
            {
                linker[v] = u;
                linker2[u] = v;
                return true;
            }    
        }  
    return false;  
}
int hungary()
{
    int res = 0;
    int u;
    memset(linker, -1, sizeof(linker));
    memset(linker2, -1, sizeof(linker2));
    for(u = 0; u < uN; u++)
    {
        memset(used, 0, sizeof(used));
        if(dfs(u))
			res++;
    }
    return res;   
}

map <long long, int> Map;
long long x[maxn], y[maxn];
long long cnt[maxn * 3];

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
#endif
	int n;
	scanf("%d", &n);
	for(int i = 0; i < n; i++) {
		long long tmp;
		scanf("%lld%lld", &x[i], &y[i]);
		tmp = x[i] + y[i];
		if(Map.find(tmp) != Map.end()) {
			G[i][Map[tmp]] = 1;
		} else {
			G[i][vN] = 1;
			Map[tmp] = vN;
			cnt[vN] = tmp;
			vN++;
		}
		tmp = x[i] - y[i];
		if(Map.find(tmp) != Map.end()) {
			G[i][Map[tmp]] = 1;
		} else {
			G[i][vN] = 1;
			Map[tmp] = vN;
			cnt[vN] = tmp;
			vN++;
		}
		tmp = x[i] * y[i];
		if(Map.find(tmp) != Map.end()) {
			G[i][Map[tmp]] = 1;
		} else {
			G[i][vN] = 1;
			Map[tmp] = vN;
			cnt[vN] = tmp;
			vN++;
		}
	}
	uN = n;
	int ans = hungary();
	if(ans != n)
		printf("impossible\n");
	else {
		for(int i = 0; i < n; i++) {
			long long tmp = cnt[linker2[i]];
			if(x[i] + y[i] == tmp) {
				printf("%lld + %lld = %lld\n", x[i], y[i], tmp);
			} else if(x[i] - y[i] == tmp) {
				printf("%lld - %lld = %lld\n", x[i], y[i], tmp);
			} else {
				printf("%lld * %lld = %lld\n", x[i], y[i], tmp);
			}
		}
	}
	return 0;
}


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值