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

来源:互联网 发布:mac os清理软件 编辑:程序博客网 时间:2024/05/29 15:14

题意:给出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_JUDGEfreopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);#endifint 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;}


阅读全文
0 0
原创粉丝点击