zoukankan      html  css  js  c++  java
  • G_M_网络流A_网络吞吐量

    调了两天的代码,到最后绝望地把I64d改成lld就过了,我真的是醉了。
    网络吞吐量

    题面:给出一张(n个点,m条边)带权(点权边权均有)无向图,点权为每个点每秒可以接受发送的最大值,边权为花费,保证数据沿着最短路径从1发送到n。
    题解:因为保证数据沿着最短路发送,所以可以求出1到n的最短路,然后将符合最短路的边全部加到网络图(一定是符合条件的所有边,而非最短路上的边,因为最短路长度唯一,而路径不唯一,故点权不唯一,所以应该将所有符合条件的边都加入),这些边的容量为INF,因为流量限制在点上,所以最短路边权不限制流量,限制工作交给点来完成。将一个点拆成入点和出点,入点到出点的边权为点权以达到限流作用,最后跑一次最大流即为所求。
    PS:这题是CQOI2015的题,不得不说这题作为专题的A是有道理的,因为是最短路+网络流拆点的模板,比较和谐。~鬼知道I64d会WA???~除此,还了解到了SPFA的两个小优化(SLF,LLL),可以说收获不小。~ISAP是真滴好写~


    #pragma comment(linkerr, "/STACK: 1024000000,1024000000")
    #include <bits/stdc++.h>
    #define pb push_back
    #define mp make_pair
    #define eb emplace_back
    #define em emplace
    #define pii pair<int,int>
    #define de(x) cout << #x << " = " << x << endl
    #define clr(a,b) memset(a,b,sizeof(a))
    #define INF (0x3f3f3f3f)
    #define LINF ((long long)(0x3f3f3f3f3f3f3f3f))
    #define F first
    #define S second
    using namespace std;
    
    const int N = 5006;
    const int M = 1e5 + 15;
    typedef long long ll;
    typedef pair<ll, int> pli;
    struct Edge
    {
    	int u, v, nxt;
    	ll w;
    };
    Edge e1[M<<2], e2[M<<2];
    int h1[N<<2], h2[N<<2], ect1, ect2;
    ll dis[N<<2];
    int d[N<<2], gap[N<<2], cur[N<<2];
    bool vis[N<<2];
    int n, m, ct;
    int a[M], b[M];
    ll c[M];
    ll val[N];
    
    void init()
    {
    	clr(vis,0);
    	clr(h1,-1); clr(h2,-1);
    	ect1 = ect2 = 0;
    }
    void _add1( int u, int v, ll w )
    {
    	e1[ect1].u = u;
    	e1[ect1].v = v;
    	e1[ect1].nxt = h1[u];
    	e1[ect1].w = w;
    	h1[u] = ect1++;
    }
    void _add2( int u, int v, ll w )
    {
    	e2[ect2].u = u;
    	e2[ect2].v = v;
    	e2[ect2].nxt = h2[u];
    	e2[ect2].w = w;
    	h2[u] = ect2++;
    }
    
    void dij( int s, int t )
    {
    	for ( int i = 1; i <= n; i ++ )
    		dis[i] = LINF;
    	dis[t] = 0;
    	priority_queue<pli> q;
    	q.push( {0ll,t} );
    	while ( !q.empty() )
    	{
    		pli nw = q.top(); q.pop();
    		int u = nw.S;
    		if ( vis[u] ) continue;
    		vis[u] = 1;
    		for ( int i = h1[u]; i+1; i = e1[i].nxt )
    		{
    			int v = e1[i].v;
    			if ( dis[v] > dis[u] + e1[i].w )
    			{
    				dis[v] = dis[u] + e1[i].w;
    				q.push( {-dis[v], v} );
    			}
    		}
    	}
    }
    
    void bfs( int s, int t )
    {
    	queue<int> q;
    	clr(d,0); clr(gap,0);
    	++gap[d[t] = 1];
    	ct = 1;
    	q.push(t);
    	while ( !q.empty() )
    	{
    		int u = q.front(); q.pop();
    		for ( int i = h2[u]; i+1; i = e2[i].nxt )
    		{
    			int v = e2[i].v;
    			if ( d[v] ) continue;
    			++gap[d[v] = d[u]+1];
    			q.push(v);
    			ct ++;
    		}
    	}
    }
    
    ll aug( int u, int s, int t, ll mi )
    {
    	if ( u == t ) return mi;
    	ll flw = 0;
    	for ( int &i = cur[u]; i+1; i = e2[i].nxt )
    	{
    		int v = e2[i].v;
    		if ( d[u] == d[v] + 1 )
    		{
    			ll tp = aug( v, s, t, min(mi,e2[i].w) );
    			flw += tp, mi -= tp, e2[i].w -= tp, e2[i^1].w += tp;
    			if ( !mi ) return flw;
    		}
    	}
    	if ( !(--gap[d[u]]) ) d[s] = ct+1;
    	++gap[++d[u]], cur[u] = h2[u];
    	return flw;
    }
    
    ll mxflw( int s, int t )
    {
    	bfs(s,t);
    	for ( int i = 1; i <= 2*n; i ++ )
    		cur[i] = h2[i];
    	ll res = aug( s, s, t, LINF );
    	while ( d[s] <= ct ) 
    		res += aug( s, s, t, LINF );
    	return res;
    }
    
    void build( int s, int t )
    {
    	queue<int> q;
    	q.push(s);
    	clr(vis,0);
    	vis[s] = 1;
    	while ( !q.empty() )
    	{
    		int u = q.front(); q.pop();
    		for ( int i = h1[u]; i+1; i = e1[i].nxt )
    		{
    			int v = e1[i].v;
    			if ( dis[u] == dis[v] + e1[i].w )
    			{
    				_add2( u+n, v, LINF ), _add2( v, u+n, 0ll );
    				if ( !vis[v] ) q.push(v), vis[v] = 1;
    			}
    		}
    	}
    }
    
    int main()
    {
    	init();
    	scanf("%d%d", &n, &m);
    	for ( int i = 0; i < m; i ++ )
    	{
    		scanf("%d%d%lld", &a[i], &b[i], &c[i]);
    		_add1(a[i],b[i],c[i]); _add1(b[i],a[i],c[i]);
    	}
    	dij(1,n);
    	build(1,n);
    	
    	for ( int i = 1; i <= n; i ++ )
    		scanf("%lld", &val[i]);
    	for ( int i = 2; i < n; i ++ )
    	{
    		_add2( i, i+n, val[i]);
    		_add2( i+n, i, 0ll );
    	}
    	int S = 1, T = n;
    	_add2( 1, 1+n, LINF ); _add2( 1+n, 1, 0ll );
    
    	ll mx = mxflw( S, T );
    	printf("%lld
    ", mx);
    	return 0;
    }
    
    /*
    3 2
    1 2 1
    2 3 1
    1
    2
    3
    */
    

  • 相关阅读:
    React中条件渲染
    React 中this.setStat是批量执行的, 它发现做三次是多余的,所以只执行一次
    React 修改获取state中的值
    POJ3417 Network (树上差分)
    POJ3349 Snowflake Snow Snowflakes(Hash)
    Codeforces Round #630 (Div. 2) C. K-Complete Word(字符串)
    Codeforces Round #630 (Div. 2) B. Composite Coloring(数论)
    Codeforces Round #630 (Div. 2) A. Exercising Walk(水题)
    Codeforces Round #629 (Div. 3)/1328 E.Tree Queries(LCA)
    洛谷P5836 [USACO19DEC]Milk Visits S(LCA/并查集)
  • 原文地址:https://www.cnblogs.com/FormerAutumn/p/10355911.html
Copyright © 2011-2022 走看看