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

  • 相关阅读:
    程序员的7中武器
    需要强化的知识
    微软中国联合小i推出MSN群Beta 不需任何插件
    XML Notepad 2006 v2.0
    Sandcastle August 2006 Community Technology Preview
    [推荐] TechNet 广播 SQL Server 2000完结篇
    《太空帝国 4》(Space Empires IV)以及 xxMod 英文版 中文版 TDM Mod 英文版 中文版
    IronPython 1.0 RC2 更新 1.0.60816
    Microsoft .NET Framework 3.0 RC1
    《Oracle Developer Suite 10g》(Oracle Developer Suite 10g)V10.1.2.0.2
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5114208.html
Copyright © 2011-2022 走看看