c/c++语言开发共享bzoj2007 NOI2010 海拔(对偶图)

80分(最小割)思路 先考虑如果没有题目中东南角为1那个限制的话会怎样。 那么只要让每个点的海拔都是0就行了。这样不论怎样走,最后的答案都是0. …

题目链接

80分(最小割)思路

先考虑如果没有题目中东南角为(1)那个限制的话会怎样。
那么只要让每个点的海拔都是(0)就行了。这样不论怎样走,最后的答案都是0.
然后再考虑那个东南角为(1)的限制表达了什么。其实说明了最后的答案一定是右下角一部分海拔全部为(1),左上角一部分海拔全部为(0)
所以这样只要找到分界点就行了。
这就是最小割的裸题啊。以((1,1))为起点,((n+1,n+1))为终点跑一遍最小割就行了。

100分(对偶图)思路

直接最小割过不去后面的大数据。所以要用对偶图优化一下。
平面图就是像题目中这样两条边的交点都是顶点的图。
如图
bzoj2007 NOI2010 海拔(对偶图)
图中(9)个方格叫做平面图的面。对于一个平面图的对偶图,就是将平面图中的每个边两边的两个面连接起来。
上图的对偶图就长这样
bzoj2007 NOI2010 海拔(对偶图)
红色部分就是对偶图了。
然后只要将原图转化成对偶图之后,跑最短路就行了。

80(90)分代码

/* * @author: wxyww * @date:   2019-02-12 11:28:33 * @last modified time: 2019-02-12 15:42:39 */ #include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> #include<ctime> #include<bitset> #include<cstring> #include<queue> 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; } queue<int>q; 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<<dinic();     return 0; }

100分代码

/* * @author: wxyww * @date:   2019-02-12 14:54:58 * @last modified time: 2019-02-12 15:31:30 */ #include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> #include<ctime> #include<bitset> #include<queue> #include<cstring> using namespace std; typedef long long ll; const int n = 501000,m = 10000000; #define pi pair<int,int> 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<pi,vector<pi>,greater<pi> >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<<dij();     return 0; }

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/605248.html

(0)
上一篇 2021年5月13日
下一篇 2021年5月13日

精彩推荐