zoukankan      html  css  js  c++  java
  • BZOJ 2561

    本题需要用一点M(in & ax)ST的性质。。

    以MinestST(这英语也是十级水平。。)为例。。假设加入边(u, v),边权为L。然后我们把所有边权小于L的边都取出来单独看。这些边不能连通u, v,否则(u,v)边绝无可能在MST中——因为在加入它之后形成的这个环中,如果去掉它,显然是最优的。

    所以以u、v为s、t,每条边权小于L的边容量置为1、跑一遍无向图最小割即可。。

    MaxestST同理。。答案只需两次相加(因为不会统计到重复的边)。。

    武神提了一个问题。。竟被吓到。。无向图最小割是什么鬼

    怎么建图?难道要拆成两个方向建四条弧!?

    不用。。只要建一个方向。。因为两个方向上不可能有同时有流量。。

    Solved...

    // BZOJ 2561
    
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
     const int N=20000+5, M=200000*2+5, INF=0x7f7f7f7f;
    
     #define rep(i,a,b) for (int i=a; i<=b; i++)
     #define dep(i,a,b) for (int i=a; i>=b; i--)
     #define read(x) scanf("%d", &x)
     #define fill(a,x) memset(a, x, sizeof(a))
    
     struct Edge {
     	int from, to, dis;
     	bool operator < (const Edge &x) const { return dis<x.dis; }
     } e[M/2];
    
     struct Graph {
     	int s, from[M], to[M], cap[M], pre[M], last[N];
     	void init() { s=-1; fill(last, -1); }
     	void ine(int a, int b, int c) {
     		s++;
     		from[s]=a, to[s]=b, cap[s]=c, pre[s]=last[a];
     		last[a]=s;
     	}
     	void ine2(int a, int b, int c1, int c2) {
     		ine(a, b, c1);
     		ine(b, a, c2);
     	}
     } G;
     #define reg(i,s,u) for (int i=s.last[u]; i!=-1; i=s.pre[i])
    
     int Q[N*4], d[N], cur[N], n, m, u, v, w;
     bool vis[N];
    
     bool BFS(int s, int t) {
     	int head=1, tail=1;
     	fill(vis, false);
     	Q[1]=s; d[s]=0; vis[s]=true;
     	while (head<=tail) {
     		int x=Q[head++];
     		reg(i,G,x) {
     			int y=G.to[i];
     			if (G.cap[i]<=0 || vis[y]) continue;
     			vis[y]=true;
     			d[y]=d[x]+1;
     			Q[++tail]=y;
     		}
     	} 
     	return vis[t];
     }
    
     int DFS(int x, int t, int a) {
     	if (x==t || a==0) return a;
     	int ret=0, flow;
     	for (int &i=cur[x]; i!=-1; i=G.pre[i]) {
     		int y=G.to[i];
     		if (d[y]==d[x]+1 && (flow=DFS(y, t, min(a, G.cap[i])))>0) {
     			G.cap[i]-=flow;
     			G.cap[i^1]+=flow;
     			a-=flow;
     			ret+=flow;
     			if (a==0) break;  // 这个break不能往前写!
     		}
     	}
     	return ret;
     }
    
     int Dinic(int s, int t) {
     	int ret=0;
     	while (BFS(s, t)) {
     		rep(i,1,n) cur[i]=G.last[i];
     		ret+=DFS(s, t, INF);
     	}
     	return ret;
     }
    
    int main()
    {
    	read(n); read(m);
    	rep(i,1,m) read(e[i].from), read(e[i].to), read(e[i].dis);
    
        int ans=0;
        sort(e+1, e+m+1);
    	read(u), read(v), read(w);
    	G.init();
    	rep(i,1,m) if (e[i].dis<w) G.ine2(e[i].from, e[i].to, 1, 1); else break;
    	ans+=Dinic(u, v);
        G.init();
        dep(i,m,1) if (e[i].dis>w) G.ine2(e[i].from, e[i].to, 1, 1); else break;
        ans+=Dinic(u, v);
    
        printf("%d
    ", ans);
    	
    	return 0;
    }
    


  • 相关阅读:
    学员操作——隔行变色
    jQuery基础及选择器(1)
    学员操作——组合继承
    JavaScript面向对象
    学员操作——创建继承person的student子类
    学员操作——flower函数
    JavaScript操作DOM(2)
    JavaScript操作DOM(1)
    学员操作——制作秒表定时器
    学员操作——制作5s关闭广告
  • 原文地址:https://www.cnblogs.com/yearwhk/p/5119876.html
Copyright © 2011-2022 走看看