平面图转对偶图19_03_21校内训练 [Everfeel]

对于每个平面图,都有唯一一个对偶图与之对应。若G‘是平面图G的对偶图,则满足:

G'中每一条边的两个节点对应着G中有公共边的面,包括最外部无限大的面。

直观地讲,红色标出来的图就是蓝色标出的图的对偶图。

 

求出一个平面图的对偶图(而且不是特殊的结构),可以贪心地找出所有最小的面。但如何描述最小?我们要固定一条边,按它顺时针或逆时针的方向找到第一条边,直到出现第一个访问过的边,就找到了一个面。

具体地将:从每个边出发,按有方向的角排序,找到角度最大或最小的边,再进行下去。反正自己写写代码就知道了。


 

例题

给出一个平面图,每个点有a和b两种属性,每个面(包括无限大的面)的价值为在这个面上的点的a总和或b总和,若相邻的面所选的属性不同,代价为所有相邻点边的点权和。最大化总价值。N≤4000。


 

思路

考场上从没写过对偶图,结果自己搞出来了.......反而最小割没写出来。

转完对偶图后,从S向每个对偶图上的点连一条比边权为该面的a价值总和的边,再从这个点向T连一条边权为该面的b价值总和的边。对于原图相邻的面,连一条权值为公共边价值和的边(这个要双向)。不难发现其最小割为最小的代价。

如:重复的边合并即可。

一个不需要代码的代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long int ll;
  4 const double pi=3.1415926535898;
  5 const ll maxn=2E5+5;
  6 const ll inf=INT_MAX;
  7 ll min(ll x,ll y){return x<y?x:y;}
  8 struct pt
  9 {
 10     double x,y;
 11     int pos;
 12     pt(double a=0,double b=0,int p=0){x=a,y=b;pos=p;}
 13     void operator=(pt A){x=A.x,y=A.y,pos=A.pos;}
 14     pt operator+(pt A){return pt(x+A.x,y+A.y,pos);}
 15     pt operator-(pt A){return pt(x-A.x,y-A.y,pos);}
 16     void out(){cout<<x<<" "<<y<<" ";}
 17 }p[maxn];
 18 ll n,m,v[maxn][2],x,y,z,cur,val[maxn][2],ans,dfn[maxn],ti,S,T;
 19 bool vis[maxn*2]; 
 20 map<int,int>next;
 21 map<pair<int,int>,int>cost;
 22 set<pair<int,int> >eS;
 23 pt rotate(pt A,double ra){return pt(A.x*cos(ra)-A.y*sin(ra),A.x*sin(ra)+A.y*cos(ra),A.pos);}
 24 pt wait[maxn];
 25 bool cmp(pt A,pt B)
 26 {
 27     double r1=atan2(A.y,A.x);
 28     double r2=atan2(B.y,B.x);
 29     if(r1<0)r1+=2*pi;
 30     if(r2<0)r2+=2*pi;
 31     return r1<r2; 
 32 }
 33 struct edge{ll to,next,from,w,bel;};
 34 struct graph
 35 {
 36     int head[maxn*2],size;
 37     graph(){size=1;}
 38     edge E[maxn*2];
 39     void add(int u,int v,ll w)
 40     {
 41         E[++size].to=v;
 42         E[size].next=head[u];
 43         E[size].w=w;
 44         E[size].from=u;
 45         head[u]=size;
 46     }
 47     void sortAngle(pt A,pt B,int r,int num)//suppose that A is the centre
 48     {
 49         B=B-A;
 50         double ra=-atan2(B.y,B.x);
 51         B=rotate(B,ra);
 52         for(int i=1;i<=r;++i)wait[i]=rotate(wait[i]-A,ra);
 53         sort(wait+1,wait+r+1,cmp);
 54         next[num]=wait[1].pos;
 55         for(int i=1;i<r;++i)
 56             next[wait[i].pos^1]=wait[i+1].pos;
 57         next[wait[r].pos^1]=num^1;
 58     }
 59     void sortAll()
 60     {
 61         for(int i=2;i<=size;++i)
 62         {
 63             if(next[i]==0)
 64             {
 65                 int L=0;
 66                 for(int j=head[E[i].to];j;j=E[j].next)
 67                 {
 68                     if(E[j].to==E[i].from)continue;
 69                     wait[++L]=p[E[j].to];
 70                     wait[L].pos=j;
 71                 }
 72                 sortAngle(p[E[i].to],p[E[i].from],L,i);
 73             }
 74         }
 75     }
 76     void dfs(int i,int pos)
 77     {
 78         ans+=v[E[i].to][0];
 79         ans+=v[E[i].to][1];
 80         vis[i]=1;
 81         E[i].bel=pos;
 82         val[pos][0]+=v[E[i].to][0];
 83         val[pos][1]+=v[E[i].to][1];
 84         i=next[i];
 85         if(vis[i])return;
 86         dfs(i,pos);
 87     }
 88     void getVal()
 89     {
 90         sortAll();
 91         for(int i=2;i<=size;++i)
 92             if(!vis[i])
 93             { 
 94                 ++cur;
 95                 dfs(i,cur);
 96             }
 97     }
 98     bool bfs()
 99     {
100         for(int i=0;i<=T;++i)dfn[i]=-1;
101         dfn[S]=0;
102         queue<int>Q;
103         Q.push(S);
104         while(Q.size())
105         {
106             int u=Q.front();
107             Q.pop();
108             for(int i=head[u];i;i=E[i].next)
109             {
110                 int v=E[i].to;
111                 if(dfn[v]!=-1||E[i].w==0)continue;
112                 dfn[v]=dfn[u]+1;
113                 Q.push(v);
114             }
115         }
116         return dfn[T]!=-1;
117     }
118     ll dinic(int u,ll up)
119     {
120         if(u==T)return up;
121         ll sum=0;
122         for(int i=head[u];i;i=E[i].next)
123         {
124             int v=E[i].to;
125             if(dfn[v]!=dfn[u]+1||E[i].w==0)continue;
126             ll g=dinic(v,min(E[i].w,up-sum));
127             E[i].w-=g;
128             E[i^1].w+=g;
129             sum+=g;
130             if(g==0)dfn[v]=-1;
131             if(sum==up)break;
132         }
133         return sum;
134     }
135 }G,flow;
136 int main()
137 {
138     freopen("everfeel.in","r",stdin);
139     freopen("everfeel.out","w",stdout);
140     ios::sync_with_stdio(false);
141     cin>>n>>n>>m;
142     for(int i=1;i<=n;++i)
143         cin>>p[i].x>>p[i].y>>v[i][0]>>v[i][1];
144     for(int i=1;i<=m;++i)
145     {
146         cin>>x>>y>>z;
147         G.add(x,y,z);
148         G.add(y,x,z);
149     }
150     G.getVal();
151     S=0;
152     T=cur+1;
153     for(int i=2;i<=G.size;i+=2)
154     {
155         pair<int,int>P=make_pair(G.E[i].bel,G.E[i^1].bel);
156         cost[P]+=G.E[i].w;
157         eS.insert(P);
158     }
159     for(set<pair<int,int> >::iterator pos=eS.begin();pos!=eS.end();++pos)
160     {
161         flow.add(pos->first,pos->second,cost[*pos]);
162         flow.add(pos->second,pos->first,cost[*pos]);
163     }
164     for(int i=1;i<=cur;++i)
165     {
166         flow.add(S,i,val[i][0]);
167         flow.add(i,S,0);
168         flow.add(i,T,val[i][1]);
169         flow.add(T,i,0);
170     }
171     ll sum=0;
172     while(flow.bfs())sum+=flow.dinic(S,inf);
173     cout<<ans-sum<<endl; 
174     return 0;
175 }
View Code
要数据请联系。

转载于:https://www.cnblogs.com/GreenDuck/p/10573577.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/425308.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

58如何调出eclipse左边文件栏

如何让windows的左侧显示 点击windows --show view--project explore 像eclipse底部的一些信息展示不见了&#xff0c;比如代码输出结果展示的 console 等都可以通过 ShowView 找到并显示出来哦&#xff0c;如果没有就去 Window -> ShowView -> other去找吧

[JAVA][算法] [字符串匹配]KMP

我们为什么需要KMP&#xff1f; 在字符串匹配问题中&#xff0c;我们需要找到匹配串pattern在原串text中的位置&#xff0c;一种显而易见的思路就是暴力匹配&#xff0c;如图所示&#xff0c;我们把pattern放置到text中的每个位置进行比较即可。 但是大家可以发现&#xff0c;…

[Leetcode][第309题][JAVA][最佳买卖股票时机含冷冻期][动态规划][压缩空间]

【问题描述】[中等] 【解答思路】 1. 动态规划 动态规划流程 第 1 步&#xff1a;设计状态 f[i]表示第 i 天结束之后的「累计最大收益」 第 2 步&#xff1a;状态转移方程 f[i][0]max(f[i−1][0],f[i−1][2]−prices[i]) f[i][1]f[i−1][0]prices[i] f[i][2]max(f[i−1][1]…

59 javabean的创建

在一个项目里定义一个java类 package srever;public class Users {private String username;private String password;public Users() {}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String g…

[剑指offer]面试题第[63]题[Leetcode][第121题][JAVA][买卖股票的最佳时机][动态规划][暴力]

【问题描述】[简单] 【解答思路】 1. 暴力 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(1) public class Solution {public int maxProfit(int prices[]) {int maxprofit 0;for (int i 0; i < prices.length - 1; i) {for (int j i 1; j < prices.leng…

60usebean创建实例对象

建立一个users的java类 package srever;public class Users {private String username;private String password;public Users() {}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPas…

ROS学习笔记四:用C++编写ROS发布与订阅

一、创建并编译功能包 1.1 创建功能包 在工作空间的 src 目录下创建功能包&#xff1a; $ cd ~/dev/catkin_ws/src $ catkin_create_pkg chapter2_tutorials std_msgs roscpp 1.2 编译功能包 进入工作目录下编译全部功能包&#xff1a; $ cd ~/dev/catkin_ws/ $ catkin_make 如…

[Leetcode][第315题][JAVA][计算右侧小于当前元素的个数][暴力][归并排序+索引数组]

【问题描述】[中等] 【解答思路】 1. 暴力 &#xff08;超时&#xff09; 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(1) public List<Integer> countSmaller(int[] nums) {List<Integer> ans new ArrayList<Integer>();int n nums.length…

61setproperty对象

建立一个users类 package srever;public class Users {private String username;private String password;public Users() {}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword(…

关于sin的导数的证明

引自JetTangs的博客 几何证明: AC切圆O于C AO交圆O于B CD、OF为水平线 BF为垂直线 令∠EOF θ 求证sinθ的导数为cosθ 证: 设∠AOC的角度为x, 由弦切角定理可知∠ACB 12x 而且∠ECDθ 则∠BCD 90-θ-12x 于是 limx→0sin(90−θ−12x)cosθ意思就是 当x无限接近于…

62 getproperty对象

定义一个login的jsp <% page language"java" import"java.util.*" contentType"text/html; charsetutf-8"%><!DOCTYPE html> <html> <head> <meta charset"ISO-8859-1"> <title>Insert title he…

Python网络爬虫之图片懒加载技术、selenium和PhantomJS

引入 今日概要 图片懒加载seleniumphantomJs谷歌无头浏览器知识点回顾 验证码处理流程今日详情 动态数据加载处理 一.图片懒加载 什么是图片懒加载&#xff1f; 案例分析&#xff1a;抓取站长素材http://sc.chinaz.com/中的图片数据 #!/usr/bin/env python # -*- coding:utf-8 …

[Leetcode][第题][JAVA][两个数组的交集 II1][双指针][HashMap]

【问题描述】[中等] 【解答思路】 1. 哈希映射 复杂度分析 class Solution {public int[] intersect(int[] nums1, int[] nums2) {if (nums1.length > nums2.length) {return intersect(nums2, nums1);}Map<Integer, Integer> map new HashMap<Integer, Intege…

63 javabean的作用域范围

定义一个users类 package srever;public class Users {private String username;private String password;public Users() {}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword(…

【Immutable】拷贝与JSON.parse(JSON.stringify()),深度比较相等与underscore.isEqual(),性能比较...

样本&#xff1a;1MB的JSON文件&#xff0c;引入后生成500份的一个数组&#xff1b; 结果如下&#xff1a; 拷贝性能&#xff1a; JSON.parse(JSON.stringify()) 的方法&#xff1a;2523.55517578125ms immutable.fromJs: 1295.159912109375ms 快了一倍 深度比较性能&#xff1…

65 modol1用户登录

定义一个Users类 package srever;public class Users {private String username;private String password;public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword() {return passwor…

[剑指offer]面试题第[58-2]题[JAVA][左旋转字符串][拼接]

【问题描述】[中等] 【解答思路】 1. 字符串切片 应用字符串切片函数&#xff0c;可方便实现左旋转字符串。 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(N) public String reverseLeftWords(String s, int n) {return s.substring(n, s.length()) s.substring(0,…

[剑指offer]面试题第[59-1]题[Leetcode][第239题][JAVA][滑动窗口的最大值][单调队列][优先队列]

【问题描述】[困难] 【解答思路】 1. 暴力 两层 for 循环&#xff0c;每次都从窗口中找最大值即可 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(N) public int[] maxSlidingWindow(int[] nums, int k) {int n nums.length;if (n 0) {return nums;}int result[]…