BZOJ1585 USACO 2009 Mar Gold 3.Earthquake Damage 2

题目大意:与http://blog.csdn.net/wyfcyx_forever/article/details/39345281这个相近。只是求的是损坏节点的最小数目。

Sol:

拆点最小割。

S->1 c=INF

提到的点x x‘->T c=INF

对于每个点x,为1或是提到的点 x->x‘ c=INF

对于每个点x,不为1且不是提到的点 x->x‘ c=1

对于原图每条边x->y x‘->y c=INF y‘->x c=INF

然后强大的ISAP模板水过。

Code:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define INF 0x3f3f3f3f

queue<int> q;

#define N 3010
#define M 20010
struct Solver {
    int head[N << 1], next[(M << 2) + N*2], end[(M << 2) + N*2], flow[(M << 2) + N*2], ind;
    int gap[N << 1], stack[N << 1], top, cur[N << 1], d[N << 1];
    void reset() {
        ind = top = 0;
        memset(head, -1, sizeof(head));
    }
    void addedge(int a, int b, int _flow) {
        int q = ind++;
        end[q] = b;
        next[q] = head[a];
        head[a] = q;
        flow[q] = _flow;
    }
    void make(int a, int b, int _flow) {
        //printf("%d %d %d\n", a, b, _flow);
        addedge(a, b, _flow);
        addedge(b, a, 0);
    }
    void make_db(int a, int b, int _flow) {
        addedge(a, b, _flow);
        addedge(b, a, _flow);
    }
    void bfs(int T) {
        memset(gap, 0, sizeof(gap));
        memset(d, -1, sizeof(d));
        ++gap[d[T] = 0];
        q.push(T);
        int i, j;
        while(!q.empty()) {
            i = q.front();
            q.pop();
            for(j = head[i]; j != -1; j = next[j])
                if (d[end[j]] == -1) {
                    ++gap[d[end[j]] = d[i] + 1];
                    q.push(end[j]);
                }
        }
    }
    int Maxflow(int S, int T) {
        bfs(T);
        memcpy(cur, head, sizeof(cur));
        int u = S, res = 0, Min, ins, i;
        bool find;
        while(d[S] < T - S + 1) {
            if (u == T) {
                Min = INF;
                for(i = 0; i < top; ++i)
                    if (Min > flow[stack[i]])
                        Min = flow[stack[i]], ins = i;
                for(i = 0; i < top; ++i)
                    flow[stack[i]] -= Min, flow[stack[i] ^ 1] += Min;
                res += Min;
                u = end[stack[top = ins] ^ 1];
            }
            if (u != T && !gap[d[u] - 1])
                break;
            find = 0;
            for(int &j = cur[u]; j != -1; j = next[j])
                if (flow[j] && d[end[j]] + 1 == d[u]) {
                    ins = j;
                    find = 1;
                    break;
                }
            if (find) {
                stack[top++] = ins;
                cur[u] = ins;
                u = end[ins];
            }
            else {
                Min = T - S + 1;
                for(int j = head[u]; j != -1; j = next[j])
                    if (flow[j] && d[end[j]] < Min) {
                        Min = d[end[j]];
                        cur[u] = j;
                    }
                if (!--gap[d[u]])
                    break;
                ++gap[d[u] = Min + 1];
                if (u != S)
                    u = end[stack[--top] ^ 1];
            }
        }
        return res;
    }
}G;

int get[N];

int main() {
    int n, m, num;
    scanf("%d%d%d", &n, &m, &num);

    int a, b, x;
    register int i, j;
    G.reset();
    G.make(0, 1, INF);
    for(i = 1; i <= m; ++i) {
        scanf("%d%d", &a, &b);
        G.make(a * 2, b * 2 - 1, INF);
        G.make(b * 2, a * 2 - 1, INF);
    }
    while(num--) {
        scanf("%d", &x);
        get[x] = 1;
    }
    G.make(1, 2, INF);
    for(i = 2; i <= n; ++i) {
        if (!get[i])
            G.make(2 * i - 1, 2 * i, 1);
        else
            G.make(2 * i - 1, 2 * i, INF), G.make(2 * i, 2 * n + 1, INF);
    }
    printf("%d", G.Maxflow(0, 2 * n + 1));

    return 0;
}
时间: 2024-10-24 11:25:18

BZOJ1585 USACO 2009 Mar Gold 3.Earthquake Damage 2的相关文章

BZOJ1584 USACO 2009 Mar Gold 2.Cleaning Up

题目大意:有长度为N的颜色段,共有m种颜色,要将其划分成若干段,每一段的费用为这一段的不同颜色的数目的平方.求最小总费用. Sol: 首先我们注意到答案不超过n,因为我们显然可以将每一个划分为一段,答案为n. 于是每一段的颜色总数不超过sqrt(n). 因此我们维护最后出现的sqrt(n)种颜色最后出现的位置,进行转移. 总的时间复杂度为O(n*sqrt(n)). Code: #include <cmath> #include <cstdio> #include <cstri

[USACO 2012 Mar Gold] Large Banner

传送门:http://www.usaco.org/index.php?page=viewproblem2&cpid=127 又是一道这种题目,遇到一次跪一次,这次终于硬着头皮看懂了题解,但是谢了代码之后还是wa了3个点(共20个),实在是找不出哪里错了,略烦... 题解真的不想写了,贴个链接叭... http://blog.csdn.net/kanosword/article/details/52585972 这道题比较冷门,官方题解看得不是太懂,上面那个链接讲得比较清楚.

【USACO 2008 Mar Gold】 3.Pearl Pairing 贪心 pq

题意:有若干个颜色,每个颜色有若干头牛. 现在将牛进行配对,使得每对颜色都不一样,有SPJ. 题解:一旦某种颜色的牛数量占当前未配对牛总数最多,那么就要群起而攻之! 利用pq或者heap解决. 代码: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 101000 #define inf

BZOJ1577 USACO 2009 Feb Gold 1.Fair Shuttle Solution

权限题,不给传送门啦!在学校OJ上交的.. 有些不开心,又是一道贪心,又是一个高级数据结构的模板,又是看了别人的题解还写崩了QAQ,蒟蒻不需要理由呀. 正经题解: 首先,我们可以由「显然成立法」得出,只要我们按照右端点排序,然后能塞多少就塞多少就一定是最优哒! 你们可以YY一下,如果一堆牛能下车就赶紧下是不是可以得出最优的呢,我感觉不对但是他们都说对 然后就是很基本的线段树维护区间的查询和修改了. 需要注意的一个小地方是如果是线段树修改区间右端点是要-1的,这个很显然. 下面是具体实现: 1 /

BZOJ1579 USACO 2009 Feb Gold 3.Revamping Trails Solution

标题效果:一个N积分m无向图边.它可以是路径k右边缘值变0,确定此时1-n最短路径长度. Sol:我以为我们考虑分层图,图复制k+1部分,每间0~k一层.代表在这个时候已经过去"自由边缘"文章编号. 层与层之间的边权值为0且为单向由上层指向下层. 这样我们以0层的1点做单源最短路径.每一层的n点的距离最小值即为答案. 仅仅只是这种点数为O(K*N),边数为O(K*M),比較慢. 我的做法是,对每一层使用heap-dijkstra算法由本层的原点更新这一层的最短路长度.然后显然能够用O(

[USACO 2009 Feb Gold] Fair Shuttle (贪心+优先队列)

题目大意:有N个站点的轻轨站,有一个容量为C的列车起点在1号站点,终点在N号站点,有K组牛群,每组数量为Mi(1≤Mi≤N),行程起点和终点分别为Si和Ei(1≤Si<Ei≤N).计算最多有多少头牛可以搭乘轻轨. 一道经典的贪心题目,每当一头牛上车的时候,如果超载,我们就优先踢出去行程终点比较远的那部分牛 而 踢出哪些行程终点较远的牛 以及 哪些在车上的牛在这站到达了终点,都可以用优先队列来维护,复杂度约为 贴上代码: 1 #include <cstdio> 2 #include <

bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害

1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害 Description Farmer John的农场里有P个牧场,有C条无向道路连接着他们,第i条道路连接着两个牧场Ai和Bi,注意可能有很多条道路连接着相同的Ai和Bi,并且Ai有可能和Bi相等.Farmer John在1号牧场里.由于地震,某些牧场被损坏,但由于信春哥,C条道路没有一条损坏.有N头奶牛,他们在不同的牧场里,于是N <= P.他们一一向Farmer John报告.第i头奶牛报告给Farm

USACO·2012·Feb Bronze &amp;&amp; 2009·Open Gold

Rope Folding [Brian Dean, 2012] 时间限制: 1 Sec 内存限制: 128 MB 题目描述 Farmer John has a long rope of length L (1 <= L <= 10,000) that he uses for various tasks around his farm. The rope has N knots tied into it at various distinct locations (1 <= N <=

bzoj1702[Usaco2007 Mar]Gold Balanced Lineup 平衡的队列*

bzoj1702[Usaco2007 Mar]Gold Balanced Lineup 平衡的队列 题意: N头牛,一共K种特色.每头牛有多种特色.[i,j]段被称为balanced当且仅当K种特色在[i,j]内拥有次数相同.求最大的[i,j]段长度.n≤100000,k≤30. 题解: 得到式子:a[i][l]-a[j][l]=a[i][l-1]-a[j][l-1],l在2..k之间,移项得a[i][l]-a[i][l-1]=a[j][l]-a[j][l-1],l在2..k之间,故可以定义一个