zoukankan      html  css  js  c++  java
  • 【UNR#3】白鸽

    题面

    http://uoj.ac/problem/389

    题解

    当我刚学欧拉回路的时候,刚刚把网络流学完,就知道欧拉回路的题可以用网络流来做,这道题就是啦。

    可以说欧拉回路是一类特殊网络流的调整问题(和上下界网络流)差不多。

    所以我曾经开过脑洞,有上下界最小流可以用费用流做,但是由于太慢被自己$D$了。

    首先,判断存在性直接用欧拉回路的理论去判就行了,

    最后已经知道是绕圈圈了,所以我们考虑如何来计算绕行的圈数。

    我们把$x$轴正半轴看成圆点的射线,每正着(从上到下)经过一次,就把答案$+1$,反着经过,就把答案$-1$(为什么?因为说明原来算在里面的一圈假了,所以要$-1$)

    答案就是原来的费用加上最大费用最大流。

    然后再把每条边随意定向,我发现了$2$个问题。

    1. 要是定向之后直接符合了判定,就假了。所以我们直接让编号小的向编号大的联就好了。
    2. 权值有正有负,很麻烦。这样我们直接定向就假设费用都能取到,这样每条边都是负的了,$spfa$就能跑到快一点了(躲开负边就行了)。。。。
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 20500
    #define S 0
    #define T (n+1)
    #define LL long long
    #define ri register int
    #define INF 1000000007
    
    using namespace std;
    
    int n,m,x[N],y[N];
    int p[N],f[N],vis[N];
    
    int getf(int x) {
      if (x==f[x]) return x;
      return f[x]=getf(f[x]);
    }
    
    inline int read() {
      int ret=0,f=0; char ch=getchar();
      while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
      while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar();
      return f?-ret:ret;
    }
    
    struct graph {
      vector<int> to,w,c;
      vector<int> ed[N];
      LL dis[N]; int cur[N];
      bool vis[N];
      void add_edge(int a,int b,int aw,int ac) {
        to.push_back(b); w.push_back(aw); c.push_back(ac);  ed[a].push_back(to.size()-1);
        to.push_back(a); w.push_back(0);  c.push_back(-ac); ed[b].push_back(to.size()-1);
      }
      bool spfa() {
        memset(dis,-0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        queue<int> q;
        dis[S]=0;q.push(S);vis[S]=1;
        while (!q.empty()) {
          int x=q.front(); q.pop();
          for (ri i=0;i<ed[x].size();i++) {
            int e=ed[x][i];
            if (dis[to[e]]<dis[x]+c[e] && w[e]) {
              dis[to[e]]=dis[x]+c[e];
              if (!vis[to[e]]) vis[to[e]]=1,q.push(to[e]);
            }
          }
          vis[x]=0;
        }
        return dis[T]>-INF;
      }
      int dfs(int x,int lim) {
        if (x==T || !lim) return lim;
        LL sum=0; vis[x]=1;
        for (ri &i=cur[x];i<ed[x].size();i++) {
          int e=ed[x][i];
          if (dis[x]+c[e]==dis[to[e]] && w[e] && !vis[to[e]]) {
            int f=dfs(to[e],min(lim,w[e]));
            w[e]-=f; w[1^e]+=f;
            lim-=f; sum+=f;
            if (!lim) return sum;
          }
        }
        return sum;
      }
      LL zkw() {
        LL ret=0;
        while (spfa()) {
          memset(vis,0,sizeof(vis));
          memset(cur,0,sizeof(cur));
          ret+=dfs(S,INF)*dis[T];
        }
        return ret;
      }
    } G;
    
    int main(){
      n=read(); m=read();
      for (ri i=1;i<=n;i++) f[i]=i;
      for (ri i=1;i<=n;i++) x[i]=read(),y[i]=read();
      int ans=0;
      for (ri i=1;i<=m;i++) {
        int u=read(),v=read();
        if (y[u]<0 && y[v]>=0) swap(u,v);
        vis[u]=vis[v]=1;
        f[getf(u)]=getf(v);
        double k=(x[u]==x[v])?-1:(y[v]-y[u]*1.0)/(x[v]*1.0-x[u]);
        if (y[u]!=y[v] && ( x[u]!=x[v] && y[u]/k<x[u] || x[u]==x[v] && x[u]>0) ) {
          if (y[u]>=0 && y[v]<0) ans++,G.add_edge(v,u,1,-2);
          else if (y[u]<0 && y[v]>=0) ans--,G.add_edge(v,u,1,2);
          else G.add_edge(v,u,1,0);
        }
        else G.add_edge(v,u,1,0);
        p[u]--; p[v]++;
      }
      for (ri i=1;i<=n;i++) if (vis[i] && getf(i)!=getf(1)) {
        puts("-1");
        return 0;
      }
      for (ri i=1;i<=n;i++) {
        if (p[i]%2!=0) {
          puts("-1");
          return 0;
        }
        if (p[i]>0) G.add_edge(S,i,p[i]/2,0); else if (p[i]<0) G.add_edge(i,T,-p[i]/2,0);
      }
      if (n==2) {
        puts("0");
        return 0;
      }
      ans+=G.zkw();
      printf("%d
    ",ans);
    }
  • 相关阅读:
    JVM-压缩指针
    JVM-Java GC分析
    MySQL 技巧
    Tomcat启动web项目报Bad version number in .class file (unable to load class ...)错误的解决方法
    关于web.xml中的<welcome-file-list>中的默认首页资料
    JS传递中文参数出现乱码的解决办法
    jquery实现奇偶行赋值不同css值
    MyBatis传入多个参数的问题
    从MYSQL数据库查出指定格式的日期
    jquery 操作实例一
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11349786.html
Copyright © 2011-2022 走看看