HDU5518 : John's Fences

求出平面图的对偶图,那么需要选择一些环,使得这些环可以异或出所有环。

对于两个不同的区域,需要用一个代价最小的环把它们区分开,这对应最小割。

那么求出对偶图的最小割树,所有树边之和就是把所有区域都区分开的最小代价。

#include<cstdio>
#include<cmath>
#include<set>
#include<algorithm>
#include<map>
using namespace std;
typedef pair<int,int>PI;
typedef long long ll;
const int N=1010,M=2010,inf=~0U>>2;
int Case,cas,n,m,cnt,i,x,y,z;map<PI,int>T;
struct P{
  int x,y;
  P(){}
  P(int _x,int _y){x=_x,y=_y;}
  ll operator*(const P&b){return 1LL*x*b.y-1LL*y*b.x;}
}a[N];
struct E{
  int x,y,z;double o;
  E(){}
  E(int _x,int _y,int _z){x=_x,y=_y,z=_z,o=atan2(a[y].x-a[x].x,a[y].y-a[x].y);}
}e[M];
bool del[M];int from[M];
namespace GetArea{
struct cmp{bool operator()(int a,int b){return e[a].o<e[b].o;}};
set<int,cmp>g[N];set<int,cmp>::iterator k;int i,j,q[M],t;
void work(){
  for(i=0;i<m+m;i++)if(!del[i]){
    for(q[t=1]=j=i;;q[++t]=j=*k){
      k=g[e[j].y].find(j^1);k++;
      if(k==g[e[j].y].end())k=g[e[j].y].begin();
      if(*k==i)break;
    }
    ll s=0;
    for(j=1;j<=t;j++)s+=a[e[q[j]].x]*a[e[q[j]].y],del[q[j]]=1;
    if(s<=0)continue;
    for(cnt++,j=1;j<=t;j++)from[q[j]]=cnt;
  }
}
}
namespace GH{
struct E{int t,f;E*nxt,*pair;}*g[N],*d[N],pool[10000],*cur;
int n,m,i,e[M][3],S,T,h[N],gap[N],maxflow,vis[N],a[N],b[N],ans;
void init(int _n){n=_n;m=ans=0;}
inline void newedge(int x,int y,int z){e[++m][0]=x;e[m][1]=y;e[m][2]=z;}
inline void add(int s,int t,int f){
  E*p=cur++;p->t=t;p->f=f;p->nxt=g[s];g[s]=p;
  p=cur++;p->t=s;p->f=0;p->nxt=g[t];g[t]=p;
  g[s]->pair=g[t];g[t]->pair=g[s];
}
inline int min(int a,int b){return a<b?a:b;}
int sap(int v,int flow){
  if(v==T)return flow;
  int rec=0;
  for(E*p=d[v];p;p=p->nxt)if(h[v]==h[p->t]+1&&p->f){
    int ret=sap(p->t,min(flow-rec,p->f));
    p->f-=ret;p->pair->f+=ret;d[v]=p;
    if((rec+=ret)==flow)return flow;
  }
  if(!(--gap[h[v]]))h[S]=T;
  gap[++h[v]]++;d[v]=g[v];
  return rec;
}
void dfs(int x){
  vis[x]=1;
  for(E*p=g[x];p;p=p->nxt)if(p->f&&!vis[p->t])dfs(p->t);
}
void solve(int l,int r){
  if(l>=r)return;
  int i;
  for(cur=pool,i=1;i<=T;i++)g[i]=d[i]=NULL,h[i]=gap[i]=0;
  for(i=1;i<=m;i++)add(e[i][0],e[i][1],e[i][2]),add(e[i][1],e[i][0],e[i][2]);
  add(S,a[l],inf),add(a[r],T,inf);
  for(gap[maxflow=0]=T,i=1;i<=T;i++)d[i]=g[i],vis[i]=0;
  while(h[S]<T)maxflow+=sap(S,inf);
  ans+=maxflow;
  dfs(S);
  int L=l,R=r;
  for(i=l;i<=r;i++)if(vis[a[i]])b[L++]=a[i];else b[R--]=a[i];
  for(i=l;i<=r;i++)a[i]=b[i];
  solve(l,R),solve(L,r);
}
int work(){
  S=n+1;T=S+1;
  for(i=1;i<=n;i++)a[i]=i;
  solve(1,n);
  return ans;
}
}
inline int getid(){
  int x,y;
  scanf("%d%d",&x,&y);
  if(T[PI(x,y)])return T[PI(x,y)];
  T[PI(x,y)]=++n;
  a[n]=P(x,y);
  return n;
}
int main(){
  scanf("%d",&Case);
  for(cas=1;cas<=Case;cas++){
    n=cnt=0;
    T.clear();
    scanf("%d",&m);
    for(i=0;i<m;i++){
      x=getid();
      y=getid();
      scanf("%d",&z);
      e[i<<1]=E(x,y,z);
      e[i<<1|1]=E(y,x,z);
    }
    for(i=0;i<m+m;i++)del[i]=from[i]=0;
    for(i=1;i<=n;i++)GetArea::g[i].clear();
    for(i=0;i<m+m;i++)GetArea::g[e[i].x].insert(i);
    GetArea::work();
    GH::init(cnt+1);
    for(i=0;i<m+m;i+=2)GH::newedge(from[i]+1,from[i^1]+1,e[i].z);
    printf("Case #%d: %d\n",cas,GH::work());
  }
  return 0;
}

  

HDU5518 : John's Fences

时间: 2024-10-22 02:06:08

HDU5518 : John's Fences的相关文章

POJ 2018 Best Cow Fences

斜率优化DP...<浅谈数形结合思想在信息学竞赛中的应用 安徽省芜湖一中 周源>例题... Best Cow Fences Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9311   Accepted: 2986 Description Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each field c

洛谷P2731 骑马修栅栏 Riding the Fences

P2731 骑马修栅栏 Riding the Fences• o 119通过o 468提交• 题目提供者该用户不存在• 标签USACO• 难度普及+/提高 提交 讨论 题解 最新讨论 • 数据有问题题目背景Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方.题目描述John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一个顶点(即

USACO6.4-Electric Fences:计算几何

Electric Fences Kolstad & Schrijvers Farmer John has decided to construct electric fences. He has fenced his fields into a number of bizarre shapes and now must find the optimal place to locate the electrical supply to each of the fences. A single wi

深搜解Riding the Fences

Riding the Fences Farmer John owns a large number of fences that must be repairedannually. He traverses the fences by riding a horse along each andevery one of them (and nowhere else) and fixing the broken parts. Farmer John is as lazy as the next fa

USACO 6.4 Electric Fences

Electric FencesKolstad & Schrijvers Farmer John has decided to construct electric fences. He has fenced his fields into a number of bizarre shapes and now must find the optimal place to locate the electrical supply to each of the fences. A single wir

USACO 3.3 Riding the Fences

Riding the Fences Farmer John owns a large number of fences that must be repaired annually. He traverses the fences by riding a horse along each and every one of them (and nowhere else) and fixing the broken parts. Farmer John is as lazy as the next

POJ2018 Best Cow Fences

Best Cow Fences Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 11175   Accepted: 3666 Description Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each field contains a certain number of cows, 1 <= ncows <

洛谷 P2731 骑马修栅栏 Riding the Fences

P2731 骑马修栅栏 Riding the Fences 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束. 每一个栅栏连接两个顶点,顶点用1到500标号(虽然有的农场并没有500个顶点).一个

POJ 2018 Best Cow Fences(二分答案)

POJ 2018 Best Cow Fences(二分答案) Best Cow Fences Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 12144 Accepted: 3958 Description Farmer John's farm consists of a long row of N (1 <= N <= >100,000)fields. Each field contains a certain nu