zoukankan      html  css  js  c++  java
  • bzoj2007 NOI2010 海拔(对偶图)

    # 80分(最小割)思路 先考虑如果没有题目中东南角为$1$那个限制的话会怎样。 那么只要让每个点的海拔都是$0$就行了。这样不论怎样走,最后的答案都是0. 然后再考虑那个东南角为$1$的限制表达了什么。其实说明了最后的答案一定是右下角一部分海拔全部为$1$,左上角一部分海拔全部为$0$。 所以这样只要找到分界点就行了。 这就是最小割的裸题啊。以$(1,1)$为起点,$(n+1,n+1)$为终点跑一遍最小割就行了。 # 100分(对偶图)思路 直接最小割过不去后面的大数据。所以要用对偶图优化一下。 平面图就是像题目中这样两条边的交点都是顶点的图。 如图 ![](https://i.imgur.com/JLrLq31.png) 图中$9$个方格叫做平面图的面。对于一个平面图的对偶图,就是将平面图中的每个边两边的两个面连接起来。 上图的对偶图就长这样 ![](https://i.imgur.com/Q6ETNSv.png) 红色部分就是对偶图了。 然后只要将原图转化成对偶图之后,跑最短路就行了。 # 80(90)分代码 ```cpp= /* * @Author: wxyww * @Date: 2019-02-12 11:28:33 * @Last Modified time: 2019-02-12 15:42:39 */ #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; #define num(x,y) (x - 1) * (n + 1) + y const int N = 500000,M = 10000000,INF = 1e9; ll read() { ll x=0,f=1;char c=getchar(); while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } struct node { int v,nxt,w; }e[M]; int head[N],ejs = 1; void add(int u,int v,int w) { e[++ejs].v = v;e[ejs].nxt = head[u];head[u] = ejs;e[ejs].w = w; e[++ejs].v = u;e[ejs].nxt = head[v];head[v] = ejs;e[ejs].w = 0; } queueq; int dep[N]; int S,T; int bfs() { memset(dep,0,sizeof(dep)); while(!q.empty()) q.pop(); dep[S] = 1;q.push(S); while(!q.empty()) { int u = q.front();q.pop(); for(int i = head[u];i;i = e[i].nxt) { int v = e[i].v; if(!dep[v] && e[i].w) { q.push(v); dep[v] = dep[u] + 1; if(v == T) return 1; } } } return 0; } int cur[N]; int dfs(int u,int now) { if(u == T) return now; int ret = 0; for(int &i = cur[u];i;i = e[i].nxt) { int v = e[i].v; if(dep[v] == dep[u] + 1 && e[i].w) { int k = dfs(v,min(now - ret,e[i].w)); e[i].w -= k; e[i ^ 1].w += k; ret += k; if(now == ret) return ret; } } return ret; } int dinic() { int ans = 0; while(bfs()) { memcpy(cur,head,sizeof(cur)); ans += dfs(S,INF); } return ans; } int main() { int n = read(); S = num(1,1);T = num(n + 1,n + 1); for(int i = 1;i <= n + 1;++i) { for(int j = 1;j <= n;++j) { int w = read(); add(num(i,j),num(i,j + 1),w); } } for(int i = 1;i <= n;++i) { for(int j = 1;j <= n + 1;++j) { int w = read(); add(num(i,j),num(i + 1,j),w); } } for(int i = 1;i <= n + 1; ++i) { for(int j = 1;j <= n;++j) { int w = read(); add(num(i,j + 1),num(i,j),w); } } for(int i = 1;i <= n;++i) { for(int j = 1;j <= n + 1; ++j) { int w = read(); add(num(i + 1,j),num(i,j),w); } } cout< #include #include #include #include #include #include #include using namespace std; typedef long long ll; const int N = 501000,M = 10000000; #define pi pair ll read() { ll x=0,f=1;char c=getchar(); while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } priority_queue,greater >q; struct node { int v,nxt,w; }e[M]; int head[N],ejs; void add(int u,int v,int w) { e[++ejs].v = v;e[ejs].w = w;e[ejs].nxt = head[u];head[u] = ejs; } int S,T; int dis[N],vis[N]; int dij() { memset(dis,0x3f,sizeof(dis)); q.push(make_pair(0,S)); dis[S] = 0; for(int i = 1;i <= T;++i) { if(q.empty()) break; pi k = q.top(); while(vis[k.second] && !q.empty()) k = q.top(),q.pop(); int u = k.second; if(vis[u]) break; vis[u] = 1; for(int i = head[u];i;i = e[i].nxt) { int v = e[i].v; if(vis[v]) continue; if(dis[v] > dis[u] + e[i].w) { dis[v] = dis[u] + e[i].w; q.push(make_pair(dis[v],v)); } } } return dis[T]; } int main() { int n = read(); int now; S = n * n + 1,T = S + 1; now = 1; for(int i = 1;i <= n + 1;++i) { for(int j = 1;j <= n;++j,++now) { int w = read(); if(i == 1) add(now,T,w); else if(i == n + 1) add(S,now - n,w); else add(now,now - n,w); } } now = 1; for(int i = 1;i <= n;++i) { for(int j = 1;j <= n + 1;++j,++now) { int w = read(); if(j == 1) add(S,now,w); else if(j == n + 1) add(--now,T,w); else add(now - 1,now,w); } } now = 1; for(int i = 1;i <= n + 1;++i) { for(int j = 1;j <= n;++j,++now) { int w = read(); if(i == 1 ||i == n + 1) continue; add(now - n,now,w); } } now = 1; for(int i = 1;i <= n;++i) { for(int j = 1;j <= n + 1;++j,++now) { int w = read(); if(j == 1 || j == n + 1) continue; add(now,now - 1,w); } --now; } cout<
  • 相关阅读:
    .NET Core 服务调用 RPC
    从Docker 到 Kubernatetes 的跃迁之路
    同步异步-多线程梳理
    Net的微服务选型之路
    Visual Studio 2019安装SSIS
    HL7协议的基本语法
    vue学习笔记
    开发常用的部分sql语句总结
    VSPD虚拟串口来调试通信接口程序
    SSRS报表工具之合并行数据
  • 原文地址:https://www.cnblogs.com/wxyww/p/10365679.html
Copyright © 2011-2022 走看看