【BZOJ 1497】[NOI2006] 最大获利

相关链接

题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1497

解题报告

这题先考虑一种特别简单的建图方式:

考虑使用最小割来解决这个问题
将基站放在一边,客户放在另外一边
这样的话,我们不妨规定最后在S集的表示不选择,T集选择
考虑每一条增光路,必然要割掉客户到T的路径,或者基站到S的路径

酱紫的话,岂不是刚好满足条件?

当然使用以下这种经典的建图方式可以更优地建图:

Code

第一种建图方式:

#include<bits/stdc++.h>
#define LL long long
using namespace std;

const int N = 55000+9;
const int M = N + 100000 << 1;
const int INF = 1e9;

int n,m,S,T,vout,head[N],nxt[M],to[M],flow[M];

inline int read() {
	char c=getchar(); int f=1,ret=0;
	while (c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
	while (c<='9'&&c>='0') {ret=ret*10+c-'0';c=getchar();}
	return ret * f;
}

inline void Add_Edge(int u, int v, int f = INF) {
	static int E = 1;
	to[++E] = v; nxt[E] = head[u]; head[u] = E; flow[E] = f;
	to[++E] = u; nxt[E] = head[v]; head[v] = E; flow[E] = 0;
}

class Network_Flow{
    int cur[N],dis[N];
    queue<int> que;
    public:
        inline int MaxFlow() {
            int ret = 0;
            while (BFS()) {
                memcpy(cur, head, sizeof(head));
                ret += DFS(S, INF);
            }   
            return ret;
        }
    private:
        inline bool BFS() {
            memset(dis,60,sizeof(dis));
            que.push(S); dis[S] = 0;
             
            while (!que.empty()) {
                int w = que.front(); que.pop();
                for (int i=head[w];i;i=nxt[i]) {
                    if (dis[to[i]] > INF && flow[i]) {
                        dis[to[i]] = dis[w] + 1;
                        que.push(to[i]);
                    }
                }
            }
            return dis[T] < INF;
        }
        int DFS(int w, int f) {
            if (w == T) return f;
            else {
                int ret = 0;
                for (int tmp,&i=cur[w];i;i=nxt[i]) {
                    if (dis[to[i]] == dis[w] + 1 && flow[i]) {
                        tmp = DFS(to[i], min(f, flow[i])); 
                        flow[i] -= tmp; flow[i^1] += tmp;
                        f -= tmp; ret += tmp;
                        if (!f) break;
                    }
                }
                return ret;
            }
        }
}Dinic;

int main() {
	n = read(); m = read();
	S = 0; T = N - 1;
	for (int i=1;i<=n;i++)
		Add_Edge(S, i, read());
	for (int i=1,t;i<=m;i++) {
		Add_Edge(read(), i+n);
		Add_Edge(read(), i+n);
		vout += (t = read());
		Add_Edge(i+n, T, t);
	}
	printf("%d\n",vout-Dinic.MaxFlow());
	return 0;
}

第二种建图方式:

#include<bits/stdc++.h>
#define LL long long
using namespace std;

const int N = 5000 + 9;
const int M = 100000 << 1;
const int INF = 1e9;

int n,m,S,T,vout,tmp[N],head[N],nxt[M],to[M],flow[M];

inline int read() {
	char c=getchar(); int f=1,ret=0;
	while (c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
	while (c<='9'&&c>='0') {ret=ret*10+c-'0';c=getchar();}
	return ret * f;
}

inline void Add_Edge(int u, int v, int f = INF, int t = 0) {
	static int E = 1;
	to[++E] = v; nxt[E] = head[u]; head[u] = E; flow[E] = f;
	to[++E] = u; nxt[E] = head[v]; head[v] = E; flow[E] = f * t;
}

class Network_Flow{
    int cur[N],dis[N];
    queue<int> que;
    public:
        inline int MaxFlow() {
            int ret = 0;
            while (BFS()) {
                memcpy(cur, head, sizeof(head));
                ret += DFS(S, INF);
            }   
            return ret;
        }
    private:
        inline bool BFS() {
            memset(dis,60,sizeof(dis));
            que.push(S); dis[S] = 0;
             
            while (!que.empty()) {
                int w = que.front(); que.pop();
                for (int i=head[w];i;i=nxt[i]) {
                    if (dis[to[i]] > INF && flow[i]) {
                        dis[to[i]] = dis[w] + 1;
                        que.push(to[i]);
                    }
                }
            }
            return dis[T] < INF;
        }
        int DFS(int w, int f) {
            if (w == T) return f;
            else {
                int ret = 0;
                for (int tmp,&i=cur[w];i;i=nxt[i]) {
                    if (dis[to[i]] == dis[w] + 1 && flow[i]) {
                        tmp = DFS(to[i], min(f, flow[i])); 
                        flow[i] -= tmp; flow[i^1] += tmp;
                        f -= tmp; ret += tmp;
                        if (!f) break;
                    }
                }
                return ret;
            }
        }
}Dinic;

int main() {
	n = read(); m = read();
	S = 0; T = N - 1;
	for (int i=1;i<=n;i++)
		Add_Edge(i, T, read() << 1);
	for (int i=1,t,x,y;i<=m;i++) {
		x = read(); y = read();
		vout += (t = read()) * 2;
		tmp[x] += t; tmp[y] += t;
		Add_Edge(x, y, t, 1);
	}
	for (int i=1;i<=n;i++) 
		Add_Edge(S, i, tmp[i]);
	printf("%d\n",vout-Dinic.MaxFlow()>>1);
	return 0;
}

19 thoughts to “【BZOJ 1497】[NOI2006] 最大获利”

  1. An outstanding share! I have just forwarded this onto a co-worker who had been conducting a little homework
    on this. And he in fact bought me lunch simply because I discovered it
    for him… lol. So allow me to reword this….
    Thank YOU for the meal!! But yeah, thanx for spending time to
    discuss this subject here on your web page.

  2. Simply want to say your article is as astounding. The clearness in your post is
    just excellent and i can assume you are an expert on this subject.
    Fine with your permission allow me to grab your feed to keep up to date with forthcoming post.
    Thanks a million and please carry on the enjoyable
    work.

  3. My partner and I stumbled over here different web page and thought
    I may as well check things out. I like what I see so now i am following you.
    Look forward to looking into your web page repeatedly.

  4. My programmer is trying to convince me to
    move to .net from PHP. I have always disliked the idea because of the costs.
    But he’s tryiong none the less. I’ve been using WordPress on various websites for about a year and am concerned about switching to another
    platform. I have heard fantastic things about blogengine.net.
    Is there a way I can transfer all my wordpress
    content into it? Any help would be really appreciated!

  5. Nice blog here! Also your site loads up very fast!
    What web host are you using? Can I get your affiliate link to your host?
    I wish my site loaded up as quickly as yours lol

  6. I am extremely impressed together with your writing
    abilities and also with the structure for your blog.

    Is this a paid subject matter or did you modify it your self?

    Either way keep up the nice quality writing, it’s uncommon to peer a great weblog like this one nowadays..

  7. Hey there just wanted to give you a quick heads up.
    The words in your post seem to be running off the screen in Opera.

    I’m not sure if this is a formatting issue or something to do with internet browser
    compatibility but I figured I’d post to let you know. The style and design look
    great though! Hope you get the issue fixed soon. Thanks

  8. I don’t even know how I finished up right here, however I assumed this post used to
    be great. I don’t recognise who you might be but certainly you’re
    going to a well-known blogger if you are not
    already. Cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *