zoukankan      html  css  js  c++  java
  • BZOJ 2661: [BeiJing wc2012]连连看( 费用流 )

    拆点, 能够消的连边, 然后跑费用流就OK了.

    ----------------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cmath>
    #include<algorithm>
     
    using namespace std;
     
    const int maxn = 2009;
    const int INF = 1 << 30;
     
    int X[maxn], Y[maxn], V, S, T;
     
    int Gcd(int x, int y) {
    return y ? Gcd(y, x % y) : x;
    }
     
    struct edge {
    int to, cap, cost;
    edge *next, *rev;
    } E[1000000], *pt = E, *head[maxn], *p[maxn];
     
    inline void Add(int u, int v, int c, int w) {
    pt->to = v;
    pt->cap = c;
    pt->cost = w;
    pt->next = head[u];
    head[u] = pt++;
    }
     
    inline void AddEdge(int u, int v, int c, int w) {
    Add(u, v, c, w);
    Add(v, u, 0, -w);
    head[u]->rev = head[v];
    head[v]->rev = head[u];
    }
     
    queue<int> q;
    bool inq[maxn];
    int d[maxn], a[maxn];
     
    int Work() {
    int Cost = 0, Flow = 0;
    for(; ; ) {
    for(int i = 0; i < V; i++)
    inq[i] = false, d[i] = INF;
    d[S] = 0;
    a[S] = INF;
    q.push(S);
    while(!q.empty()) {
    int x = q.front(); q.pop();
    inq[x] = false;
    for(edge* e = head[x]; e; e = e->next) if(e->cap && d[e->to] > d[x] + e->cost) {
    d[e->to] = d[x] + e->cost;
    p[e->to] = e;
    a[e->to] = min(a[x], e->cap);
    if(!inq[e->to])
    q.push(e->to), inq[e->to] = true;
    }
    }
    if(d[T] == INF)
    break;
    Flow += a[T];
    Cost += d[T] * a[T];
    for(int x = T; x != S; x = p[x]->rev->to) {
    p[x]->cap -= a[T];
    p[x]->rev->cap += a[T];
    }
    }
    printf("%d %d ", Flow >> 1, -Cost >> 1);
    }
     
    void Init() {
    S = 0; T = 1; V = 2;
    int l, r;
    scanf("%d%d", &l, &r);
    for(int i = l; i <= r; i++)
    X[i] = V++, Y[i] = V++;
    for(int i = l; i <= r; i++)
    for(int j = l; j < i; j++) {
    int v = i * i - j * j, t = (int) sqrt(v);
    if(t * t == v && Gcd(j, t) == 1) {
    AddEdge(X[j], Y[i], 1, -i - j);
    AddEdge(X[i], Y[j], 1, -i - j);
    }
    }
    for(int i = l; i <= r; i++) {
    AddEdge(S, X[i], 1, 0);
    AddEdge(Y[i], T, 1, 0);
    }
    }
     
    int main() {
    Init();
    Work();
    return 0;
    }

    ---------------------------------------------------------------------------------------- 

    2661: [BeiJing wc2012]连连看

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 844  Solved: 317
    [Submit][Status][Discuss]

    Description

     凡是考智商的题里面总会有这么一种消除游戏。不过现在面对的这关连连看可不是QQ游戏里那种考眼力的游戏。我们的规则是,给出一个闭区间[a,b]中的全部整数,如果其中某两个数x,y(设x>y)的平方差x2-y2是一个完全平方数z2,并且y与z互质,那么就可以将x和y连起来并且将它们一起消除,同时得到x+y点分数。那么过关的要求就是,消除的数对尽可能多的前提下,得到足够的分数。快动手动笔算一算吧。

    Input

            
     只有一行,两个整数,分别表示a,b。

    Output

     两个数,可以消去的对数,及在此基础上能得到的最大分数。

    Sample Input

    1 15

    Sample Output

    2 34

    HINT

    对于30%的数据,1<=a,b<=100

    对于100%的数据,1<=a,b<=1000

    Source

  • 相关阅读:
    uni_app 跳转到外部html5 的页面 (web-view) 的一些使用
    vue初学备份(动态切换class类)
    MySQL数据库基本操作
    蛋疼的JavaScript(二)this
    Java中的String,StringBuffer和StringBuilder
    LintCode_1 单例模式
    [转载]C语言EOF是什么?
    Python中的枚举
    对BOM的总结
    python类相关总结(持续更新)
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5114208.html
Copyright © 2011-2022 走看看