• 【 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

  • 相关阅读:
    毕业设计进度:3月8日
    毕业设计进度:3月7日
    毕业设计进度:3月6日
    毕业设计进度:3月5日
    深拷贝、浅拷贝
    itertools模块中的product方法
    confusion_matrix函数的使用
    sklearn中的交叉验证(Cross-Validation)
    python pandas(ix & iloc &loc)
    Python: sklearn库——数据预处理
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5573672.html
Copyright © 2020-2023  润新知