首页 > 其他分享 >hdu 1853 Cyclic Tour(费用流OR二分图最佳匹配,5级)

hdu 1853 Cyclic Tour(费用流OR二分图最佳匹配,5级)

时间:2023-03-24 15:31:43浏览次数:54  
标签:hdu work Cyclic int 1853 tours each include dis



O - Cyclic Tour


Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u


Submit  Status


System Crawler  (2013-05-30)



Description



There are N cities in our country, and M one-way roads connecting them. Now Little Tom wants to make several cyclic tours, which satisfy that, each cycle contain at least two cities, and each city belongs to one cycle exactly. Tom wants the total length of all the tours minimum, but he is too lazy to calculate. Can you help him?



 



Input



There are several test cases in the input. You should process to the end of file (EOF).
The first line of each test case contains two integers N (N ≤ 100) and M, indicating the number of cities and the number of roads. The M lines followed, each of them contains three numbers A, B, and C, indicating that there is a road from city A to city B, whose length is C. (1 ≤ A,B ≤ N, A ≠ B, 1 ≤ C ≤ 1000).



 



Output



Output one number for each test case, indicating the minimum length of all the tours. If there are no such tours, output -1. 



 



Sample Input



6 9
1 2 5
2 3 5
3 1 10
3 4 12
4 1 8
4 6 11
5 4 7
5 6 9
6 5 4
6 5
1 2 1
2 3 1
3 4 1
4 5 1
5 6 1



 



Sample Output



42 -1



Hint



In the first sample, there are two cycles, (1->2->3->1) and (6->5->4->6) whose length is 20 + 22 = 42.



 


#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define clr(f,z) memset(f,z,sizeof(f))
using namespace std;
const int mm=234;
const int oo=1e9;
bool vis[mm];
int head[mm],edge,work[mm],dis[mm],src,dest,node;
class Edge
{
  public:int v,next,flow,cost;
}e[mm*mm*2];
void data()
{
  clr(head,-1);edge=0;
}
void add(int u,int v,int _flow,int _cost)
{
  e[edge].v=v;e[edge].flow=_flow;e[edge].cost=_cost;e[edge].next=head[u];head[u]=edge++;
  e[edge].v=u;e[edge].flow=0;e[edge].cost=-_cost;e[edge].next=head[v];head[v]=edge++;
}
bool spfa()
{
  FOR(i,0,node)dis[i]=oo,vis[i]=0;
  queue<int>Q;work[src]=work[dest]=-1;
  Q.push(src);int u,v;dis[src]=0;
  while(!Q.empty())
  {
    u=Q.front();Q.pop();vis[u]=0;
    for(int i=head[u];~i;i=e[i].next)
    {
      v=e[i].v;
      if(e[i].flow&&dis[v]>dis[u]+e[i].cost)
      {
        dis[v]=dis[u]+e[i].cost;work[v]=i^1;//path
        if(vis[v])continue;vis[v]=1;Q.push(v);
      }
    }
  }
  //FOR(i,0,node)printf("d=%d %d\n",i,dis[i]);
  return work[dest]!=-1;
}
int max_spfa(int& many)
{
  int ret=0,num;
  while(spfa())
  {
    num=oo;//puts("++");
    for(int i=work[dest];~i;i=work[e[i].v])
    {
      if(e[i^1].flow<num)num=e[i^1].flow;
    }
    ret+=num*dis[dest];many+=num;
    for(int i=work[dest];~i;i=work[e[i].v])
      e[i^1].flow-=num,e[i].flow+=num;
  }
  return ret;
}
int n,m;
int main()
{ int a,b,c;
  while(~scanf("%d%d",&n,&m))
  {
    data();src=0;dest=n+n+1;node=n+n+2;
    FOR(i,1,n)add(src,i,1,0),add(i+n,dest,1,0);
    FOR(i,1,m)
    {
      scanf("%d%d%d",&a,&b,&c);
      add(a,b+n,1,c);
    }
    int ret=0,ans;
    ans=max_spfa(ret);
    //cout<<ret<<endl;
    if(ret==n)
      printf("%d\n",ans);
    else printf("-1\n");
  }
  return 0;
}






标签:hdu,work,Cyclic,int,1853,tours,each,include,dis
From: https://blog.51cto.com/u_15953788/6147355

相关文章

  • A strange lift HDU - 1548 (BFS)
    题意:第i个火车站都有一个数字Ki(0≤Ki≤N),火车在第i站只能前进Ki站或后退Ki站。火车只能在第1站和第N站之间行驶。请问,从第a站到第b站最少需前进或后退......
  • How Many Tables HDU - 1213(并查集/连通块数量)
    题意:朋友的朋友是朋友如果A认识B,B认识C,那么ABC三个人就可以坐在同一张桌子上但如果A认识B,C认识D,那我们就默认AB和CD不认识,需要准备两张桌子现在我们需要你计算出,我们一......
  • Red and Black HDU - 1312 (连通块的大小)
    题意:求某点所在连通块的大小。分析:由某点进行dfs,每次标记该点,并计数。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;constintN=110,INF=......
  • 变形课 HDU - 1181 (dfs)
    题意:给定多个单词,每个单词的首字母可以到末字母,问能否由'b'到'm'。分析:将每个单词首尾字母建图,dfs('b')将能到的所有字母进行标记,最后检查'm'是否被标记。#include......
  • 多线程面试——CountDownLatch,CyclicBarrier,Semaphore
    0.总结1.CountDownLatch是1个线程等待其他线程,CyclicBarrier是多个线程相互等待;2.CountDownLatch是计数-1,直到减为0,CyclicBarrier是计数+1,直到达到指定值;3.CountDownLatch......
  • JUC 常用 4 大并发工具类 CountDownLatch、CyclicBarrier、Semaphore、ExChanger
    文章目录​​什么是JUC?​​​​4大常用并发工具类​​​​CountDownLatch​​​​CyclicBarrier​​​​Semaphore​​​​Exchanger​​什么是JUC?JUC就是java.util.concu......
  • CountDownLatch 和 CyclicBarrier 的区别?
    CyclicBarrier它允许一组线程互相等待,直到到达某个公共屏障点(CommonBarrierPoint)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时CyclicBarrier......
  • CountDownLatch与CyclicBarrier分析及其区别
    相同点:CountDownLatch、CyclicBarrier均在jdk1.5引入的,并且都在concurrent包(用于并发处理)下。均用于实现线程同步。差异点:1CountDownLatch计数器只能使用一次。CyclicB......
  • HDU 6514 Monitor
    注意:注意要用scanf注意多测#include<iostream>#include<vector>usingnamespacestd;intn,m,q;vector<vector<int>>a;voidinsert(intx1,inty1,intx......
  • 【线程同步工具】CyclicBarrier源码分析
    在指定状态点同步任务Java并发API提供了可以使多个线程在一个指定点同步的工具类CyclicBarrier,该类前文介绍的CountDownLatch有些类似,但是它的一些特殊性使得其更为......