• 【 UVALive


    Description

    In a country there are n cities connected by m one way roads. You can paint any of these roads. To paint a road it costs d unit of money where d is the length of that road. Your task is to paint some of the roads so that the painted roads can be partitioned into some disjoint cycles such that every vertex appears in exactly k of these disjoint cycles. But you have to minimize the costs of painting these roads. 

    Input

    First line of the input contains T the number of test case. Then following lines contains T Test cases. Each case starts with a line containing 3 integers n (1 ≤ n ≤ 40), m (1 ≤ m ≤ 2000) and k (1 ≤ k and 1 ≤ k ∗ n ≤ 100). Next m lines contain description of m roads. Each line contains three integers f, t (0 ≤ f, t < n and f ̸= t) and d (0 ≤ d < 100). That means there is a road of d length from city f to city t. You can assume that there will be at most one road in one direction between two cities.

    Output 

    For each test case output contains 1 integer denoting the minimum unit of money needed to paint roads. In the case it is impossible to paint the roads maintaining the constraints output ‘-1’.

    Sample Input
    4
    4 8 1
    0 1 1
    1 0 2
    2 3 1
    3 2 2
    0 2 5
    2 0 6
    1 3 5
    3 1 6
    4 8 1
    0 1 1
    1 0 10
    2 3 10
    3 2 1
    0 2 10
    2 0 1
    1 3 1
    3 1 10
    4 8 2
    0 1 1
    1 0 2
    2 3 1
    3 2 2
    0 2 5
    2 0 6
    1 3 5
    3 1 6
    3 4 1
    0 1 5
    1 0 6
    0 2 7
    2 0 8


    Sample Output
    6
    4
    28
    -1

    【题意】

        有n个点,m条边的有向图,选一些边使得这些边组成若干无公共边的回路(回路不经过重复的点),使得每个点恰好在k个回路上,求满足条件的最小边权和。

    【分析】

     普通的就拆边,加费用跑费用流判满流。对于新加的约束——每个点必须经过k遍,就把一个点拆成两个点,建上下界流量都为k,一个点只连入边,一个点只连出边即可。

    代码如下:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 #define Maxn 110
      9 #define Maxm 110000
     10 #define INF 0xfffffff
     11 
     12 struct node
     13 {
     14     int x,y,f,c,o,next;
     15 }t[Maxm];int len;
     16 
     17 int st,ed,sum;
     18 int dis[Maxn],pre[Maxn],flow[Maxn],first[Maxn];
     19 bool inq[Maxn];
     20 
     21 int mymin(int x,int y) {return x<y?x:y;}
     22 
     23 void ins(int x,int y,int f,int c)
     24 {
     25     if(f==0) return ;
     26     if(x==st) sum+=f;
     27     t[++len].x=x;t[len].y=y;t[len].f=f;t[len].c=c;
     28     t[len].next=first[x];first[x]=len;t[len].o=len+1;
     29     t[++len].x=y;t[len].y=x;t[len].f=0;t[len].c=-c;
     30     t[len].next=first[y];first[y]=len;t[len].o=len-1;
     31 }
     32 
     33 void make_edge(int x,int y,int k1,int k2,int c)
     34 {
     35     ins(st,y,k2,c);
     36     ins(x,ed,k2,0);
     37     ins(y,x,k2-k1,-c);
     38 }
     39 
     40 queue<int > q;
     41 bool bfs()
     42 {
     43     while(!q.empty()) q.pop();
     44     memset(pre,-1,sizeof(pre));
     45     memset(inq,0,sizeof(inq));
     46     memset(dis,63,sizeof(dis));
     47     pre[st]=0;flow[st]=INF;inq[st]=1;
     48     dis[st]=0;q.push(st);
     49     while(!q.empty())
     50     {
     51         int x=q.front(),y,i;
     52         for(i=first[x];i;i=t[i].next) if(t[i].f>0)
     53         {
     54             y=t[i].y;
     55             if(dis[y]>dis[x]+t[i].c)
     56             {
     57                 pre[y]=i;
     58                 dis[y]=dis[x]+t[i].c;
     59                 flow[y]=mymin(t[i].f,flow[x]);
     60                 if(!inq[y]) {q.push(y);inq[y]=1;}
     61             }
     62         }
     63         q.pop();inq[x]=0;
     64     }
     65     if(pre[ed]==-1) return 0;
     66     return flow[ed];
     67 }
     68 
     69 void max_flow()
     70 {
     71     int ans=0,a,h=0;
     72     while(a=bfs())
     73     {
     74         int now=ed;ans+=a*dis[ed];
     75         while(now!=st)
     76         {
     77             t[pre[now]].f-=a;
     78             t[t[pre[now]].o].f+=a;
     79             now=t[pre[now]].x;
     80         }
     81         h+=a;
     82     }
     83     if(sum!=h) printf("-1
    ");
     84     else printf("%d
    ",ans);
     85 }
     86 
     87 
     88 int main()
     89 {
     90     int T;
     91     scanf("%d",&T);
     92     while(T--)
     93     {
     94         int n,m,k;
     95         scanf("%d%d%d",&n,&m,&k);
     96         memset(first,0,sizeof(first));
     97         len=0;sum=0;
     98         st=2*n+1;ed=st+1;
     99         for(int i=1;i<=m;i++)
    100         {
    101             int x,y,c;
    102             scanf("%d%d%d",&x,&y,&c);
    103             x++;y++;
    104             make_edge(x+n,y,0,1,c);
    105         }
    106         for(int i=1;i<=n;i++) make_edge(i,i+n,k,k,0);
    107         max_flow();
    108     }
    109     return 0;
    110 }
    [LA2197]

    2016-06-10 14:59:16

  • 相关阅读:
    Yii框架2.0 数据库操作初接触
    Yii框架2.0的视图和widgets表单的使用
    Yii框架2.0的安装过程
    监控之snmpd 服务
    在HTML里面HEAD部分的META元素要表达的内容是什么
    被table单元格colspan属性折磨了
    excel模版从xp复制到win7系统后出现错误 运行时错误 '429' ActiveX 部件不能创建对象
    oracle左连接连表查询
    Nginx 关闭防火墙
    左连接不能与or否则in连用
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5573672.html
Copyright © 2020-2023  润新知