zoukankan      html  css  js  c++  java
  • hit2739

    好题,回路的问题一般都要转化为度数来做
    若原图的基图不连通,或者存在某个点的入度或出度为0则无解。
    统计所有点的入度出度之差di
    对于di>0的点,加边(s,i,di,0);
    对于di<0的点,加边(i,t,-di,0);
    对原图中的每条边(i,j),在网络中加边(i,j,inf,边权),
    最小费用流的解加上原图所有边权和即为答案。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 
      6 using namespace std;
      7 struct way{int po,next,flow,cost;} e[40010];
      8 const int inf=100000007;
      9 int pre[110],p[110],cur[110],d[110],fa[110],cd[110],rd[110],q[2000010];
     10 bool v[110];
     11 int n,m,len,t;
     12 
     13 int getf(int x)
     14 {
     15     if (fa[x]!=x) fa[x]=getf(fa[x]);
     16     return fa[x];
     17 }
     18 
     19 bool check()
     20 {
     21     for (int i=1; i<=n; i++)
     22         if (!rd[i]||!cd[i]||getf(i)!=getf(1)) return 0;
     23     return 1;
     24 }
     25 
     26 void add(int x,int y,int f,int c)
     27 {
     28      e[++len].po=y;
     29      e[len].flow=f;
     30      e[len].cost=c;
     31      e[len].next=p[x];
     32      p[x]=len;
     33 }
     34 
     35 void build(int x,int y, int f, int c)
     36 {
     37      add(x,y,f,c);
     38      add(y,x,0,-c);
     39 }
     40 
     41 bool spfa()
     42 {
     43      int f=1,r=1;
     44      for (int i=1; i<=t; i++) d[i]=inf;
     45      memset(v,false,sizeof(v));
     46      d[0]=0; q[1]=0;
     47      while (f<=r)
     48      {
     49            int x=q[f++];
     50            v[x]=0;
     51            for (int i=p[x]; i!=-1; i=e[i].next)
     52            {
     53                int y=e[i].po;
     54                if (e[i].flow&&d[x]+e[i].cost<d[y])
     55                {
     56                   d[y]=d[x]+e[i].cost;
     57                   pre[y]=x; cur[y]=i;
     58                   if (!v[y])
     59                   {
     60                      q[++r]=y;
     61                      v[y]=1;
     62                   }
     63                }
     64            }
     65      }
     66      return d[n]<inf;
     67 }
     68 
     69 int mincost()
     70 {
     71     int j,s=0;
     72     while (spfa())
     73     {
     74           int neck=inf;
     75           for (int i=t; i; i=pre[i])
     76           {
     77               j=cur[i];
     78               neck=min(neck,e[j].flow);
     79           }
     80           s+=d[t]*neck;
     81           for (int i=t; i; i=pre[i])
     82           {
     83               j=cur[i];
     84               e[j].flow-=neck;
     85               e[j^1].flow+=neck;
     86           }
     87     }
     88     return s;
     89 }
     90 
     91 int main()
     92 {
     93     int cas;
     94     scanf("%d",&cas);
     95     while (cas--)
     96     {
     97         scanf("%d%d",&n,&m);
     98         memset(p,255,sizeof(p)); len=-1;
     99         memset(rd,0,sizeof(rd));
    100         memset(cd,0,sizeof(cd));
    101         for (int i=1; i<=n; i++) fa[i]=i;
    102         int ans=0;
    103         for (int i=1; i<=m; i++)
    104         {
    105             int x,y,u,v,z;
    106             scanf("%d%d%d",&x,&y,&z);
    107             cd[++x]++;rd[++y]++;
    108             build(x,y,inf,z);
    109             u=getf(x),v=getf(y);
    110             if (u!=v) fa[u]=v;
    111             ans+=z;
    112         }
    113         if (!check())
    114         {
    115             puts("-1");
    116             continue;
    117         }
    118         t=n+1;
    119         for (int i=1; i<=n; i++)
    120             if (rd[i]>cd[i]) build(0,i,rd[i]-cd[i],0);
    121             else build(i,t,cd[i]-rd[i],0);
    122         ans+=mincost();
    123         printf("%d
    ",ans);
    124     }
    125 }
    View Code
  • 相关阅读:
    Ackerman 函数奇怪的函数
    HDU2871 Memory Control 线段树区间合并
    HDU3667 Hotel 线段树 经典空间合并
    图论
    HDU3016 Man Down 线段树
    HDU1878 欧拉回路 判定是否存在欧拉回路
    从今开始
    如何打开注册表编辑器
    ASP.NET中TextBox控件设置ReadOnly="true"后台取不到值
    学习笔记(2011年5月到9月)
  • 原文地址:https://www.cnblogs.com/phile/p/6345068.html
Copyright © 2011-2022 走看看