zoukankan      html  css  js  c++  java
  • Codeforces 1517G Starry Night Camping

    将点按照 (x) 坐标的奇偶性,(y) 坐标的奇偶性分为 (4) 类,可以发现如下性质:

    1. 每一个不满足题意的平行四边形都包含了 (4) 类点恰好一个。
    2. 每一个不满足题意的平行四边形都可以表示为 ( ext{(odd, odd)} o ext{(even, odd)} o ext{(even, even)} o ext{(odd, even)}) 的一条道路。

    image.png

    于是题目转化为,丢掉总权值最小的点,使得不存在这样的道路,这是一个最小割模型。

    具体的,删点的话可以考虑拆点,将每个点 (u) 表示为 (u_{in}, u_{out}) 两个点。

    根据路径经过的顺序,将上面那 (4) 类点分为 (A, B, C, D),同时建立源点 (S) 和汇点 (T)

    图为:

    • (u_{in} o u_{out}) 连容量为 (w_u) 的边。
    • (S o a_{in} (a in A)) 连容量为 (+infty) 的边。
    • (a_{out} o b_{in} (a in A, b in B, ext{dist}(a, b) = 1)) 连容量为 (+infty) 的边。
    • (b_{out} o c_{in} (b in B, c in C, ext{dist}(b, c) = 1)) 连容量为 (+infty) 的边。
    • (c_{out} o d_{in} (c in C, d in D, ext{dist}(c, d) = 1)) 连容量为 (+infty) 的边。
    • (d_{out} o T (d in D)) 连容量为 (+infty) 的边。

    求最小割即可,边数和点数都是 (O(n)) 级别的。

    #include <bits/stdc++.h>
    #define int long long
    #define Get(x) ((x % 2 + 2) % 2)
    using namespace std;
    const int N = 2005, M = 10005;
    struct edge
    {
    	int v, w, nxt;
    } e[M << 1];
    int cnt = -1, n, m, s, t, maxflow, h[N], lev[N], cur[N];
    inline void AddEdge(int u, int v, int w)
    {
    	e[++cnt] = (edge){v, w, h[u]}; h[u] = cnt;
    	e[++cnt] = (edge){u, 0, h[v]}; h[v] = cnt;
    }
    int DFS(int u, int canflow)
    {
    	if(u == t) return canflow;
    	int resflow = 0;
    	for(int& i = cur[u]; ~i; i = e[i].nxt)
    	{
    		int v = e[i].v;
    		if(lev[v] == lev[u] + 1 && e[i].w > 0)
    		{
    			int willflow = DFS(v, min(e[i].w, canflow));
    			canflow -= willflow;
    			resflow += willflow;
    			e[i].w -= willflow;
    			e[i ^ 1].w += willflow;
    			if(!canflow) break;
    		}
    	}
    	if(!resflow) lev[u] = -1;
    	return resflow;
    }
    bool BFS()
    {
    	memset(lev, -1, sizeof lev);
    	queue<int> que;
    	que.push(t);
    	lev[t] = 998244353;
    	while(!que.empty())
    	{
    		int u = que.front(); que.pop();
    		for(int i = h[u]; ~i; i = e[i].nxt)
    		{
    			int v = e[i].v;
    			if(lev[v] != -1 || e[i ^ 1].w <= 0) continue;
    			lev[v] = lev[u] - 1;
    			if(v == s) return true;
    			que.push(v); 
    		}
    	}
    	return lev[s] != -1;
    }
    void Dinic()
    {
    	while(BFS())
    	{
    		memcpy(cur, h, sizeof h);
    		maxflow += DFS(s, INT_MAX);
    	}
    }
    int x[N], y[N], w[N], type[N], sum;
    signed main()
    {
    	ios::sync_with_stdio(false);
    	memset(h, -1, sizeof h);
    	cin >> n;
    	for(int i = 1; i <= n; i++) { cin >> x[i] >> y[i] >> w[i]; sum += w[i]; }
    	s = 1; t = n * 2 + 2;
    	for(int i = 1; i <= n; i++)
    	{
    		if(Get(x[i]) == 1 && Get(y[i]) == 1) type[i] = 1;
    		if(Get(x[i]) == 0 && Get(y[i]) == 1) type[i] = 2;
    		if(Get(x[i]) == 0 && Get(y[i]) == 0) type[i] = 3;
    		if(Get(x[i]) == 1 && Get(y[i]) == 0) type[i] = 4;
    	}
    	for(int i = 1; i <= n; i++) AddEdge(i << 1, i << 1 | 1, w[i]);
    	for(int i = 1; i <= n; i++) if(type[i] == 1) AddEdge(s, i << 1, LLONG_MAX / 64);
    	for(int i = 1; i <= n; i++) if(type[i] == 1)
    		for(int j = 1; j <= n; j++) if(type[j] == 2)
    			if(abs(x[i] - x[j]) + abs(y[i] - y[j]) == 1)
    				AddEdge(i << 1 | 1, j << 1, LLONG_MAX / 64);
    	for(int i = 1; i <= n; i++) if(type[i] == 2)
    		for(int j = 1; j <= n; j++) if(type[j] == 3)
    			if(abs(x[i] - x[j]) + abs(y[i] - y[j]) == 1)
    				AddEdge(i << 1 | 1, j << 1, LLONG_MAX / 64);
    	for(int i = 1; i <= n; i++) if(type[i] == 3)
    		for(int j = 1; j <= n; j++) if(type[j] == 4)
    			if(abs(x[i] - x[j]) + abs(y[i] - y[j]) == 1)
    				AddEdge(i << 1 | 1, j << 1, LLONG_MAX / 64);
    	for(int i = 1; i <= n; i++) if(type[i] == 4) AddEdge(i << 1 | 1, t, LLONG_MAX / 64);
    	Dinic();
    	cout << sum - maxflow << endl;
    	return 0;
    }
    
  • 相关阅读:
    EF Load之详讲
    WPF系列 自定控件
    EF6 的性能优化
    WPF系列 Path表示语法详解(Path之Data属性语法)
    WPFTookit Chart 高级进阶
    WPFTookit Chart 入门
    WPF系列-CheckBox
    WPF系列 Style
    ASP.NET MVC 5 with EF 6 上传文件
    WPF Prism
  • 原文地址:https://www.cnblogs.com/syksykCCC/p/CF1517G.html
Copyright © 2011-2022 走看看