hdu 3435 图回路分割

将一个无向图分成许多回路,回路点交集为空,点幷集为V。幷最小化回路边权和。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #include <vector>
 5 #define maxn 2010
 6 #define oo 0x3f3f3f3f
 7 using namespace std;
 8
 9 struct Edge {
10     int u, v, c, f;
11     Edge( int u, int v, int c, int f ):u(u),v(v),c(c),f(f){}
12 };
13 struct Mcmf {
14     int n, src, dst;
15     vector<Edge> edge;
16     vector<int> g[maxn];
17     int dis[maxn], pth[maxn], ext[maxn];
18
19     void init( int n, int src, int dst ) {
20         this->n = n;
21         this->src = src;
22         this->dst = dst;
23         for( int u=1; u<=n; u++ )
24             g[u].clear();
25         edge.clear();
26     }
27     void add_edge( int u, int v, int c, int f ) {
28         g[u].push_back( edge.size() );
29         edge.push_back( Edge(u,v,c,f) );
30         g[v].push_back( edge.size() );
31         edge.push_back( Edge(v,u,-c,0) );
32     }
33     bool spfa( int &flow, int &cost ) {
34         queue<int> qu;
35         memset( dis, 0x3f, sizeof(dis) );
36         qu.push( src );
37         dis[src] = 0;
38         pth[src] = -1;
39         ext[src] = true;
40         while( !qu.empty() ) {
41             int u=qu.front();
42             qu.pop();
43             ext[u] = false;
44             for( int t=0; t<g[u].size(); t++ ) {
45                 Edge &e = edge[g[u][t]];
46                 if( e.f && dis[e.v]>dis[e.u]+e.c ) {
47                     dis[e.v] = dis[e.u]+e.c;
48                     pth[e.v] = g[u][t];
49                     if( !ext[e.v] ) {
50                         ext[e.v] = true;
51                         qu.push( e.v );
52                     }
53                 }
54             }
55         }
56         if( dis[dst]==oo ) return false;
57         int flw = oo;
58         for( int eid=pth[dst]; eid!=-1; eid=pth[edge[eid].u] )
59             flw = min( flw, edge[eid].f );
60         for( int eid=pth[dst]; eid!=-1; eid=pth[edge[eid].u] ) {
61             edge[eid].f -= flw;
62             edge[eid^1].f += flw;
63         }
64         flow += flw;
65         cost += flw*dis[dst];
66         return true;
67     }
68     bool mcmf( int &flow, int &cost ) {
69         flow = cost = 0;
70         while(spfa(flow,cost));
71         return true;
72     }
73 };
74
75 int n, m;
76 Mcmf M;
77
78 int main() {
79     int T;
80     scanf( "%d", &T );
81     for( int cas=1; cas<=T; cas++ ) {
82         printf( "Case %d: ", cas );
83         scanf( "%d%d", &n, &m );
84         M.init( n+n+2, n+n+1, n+n+2 );
85         for( int i=1,u,v,w; i<=m; i++ ) {
86             scanf( "%d%d%d", &u, &v, &w );
87             M.add_edge( u, v+n, w, 1 );
88             M.add_edge( v, u+n, w, 1 );
89         }
90         for( int u=1; u<=n; u++ ) {
91             M.add_edge( M.src, u, 0, 1 );
92             M.add_edge( u+n, M.dst, 0, 1 );
93         }
94         int flow, cost;
95         M.mcmf( flow, cost );
96         if( flow!=n ) printf( "NO\n" );
97         else printf( "%d\n", cost );
98     }
99 }

时间: 2024-10-29 16:46:46

hdu 3435 图回路分割的相关文章

hdu 1853 Cyclic Tour &amp;&amp; hdu 3435 A new Graph Game(简单KM算法)

Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Total Submission(s): 1478    Accepted Submission(s): 750 Problem Description There are N cities in our country, and M one-way roads connecting them. Now L

【HDU 3435】 A new Graph Game (KM|费用流)

A new Graph Game Problem Description An undirected graph is a graph in which the nodes are connected by undirected arcs. An undirected arc is an edge that has no arrow. Both ends of an undirected arc are equivalent--there is no head or tail. Therefor

GCO3.0的图割分割算法应用(三)

该部分对图割算法工具箱(GCO3.0)具体怎么实现简单图像的分割做一个实例. 相关理论介绍以及工具箱的介绍见先前博客: - 图像分割之图割工具箱GCO3.0的使用(二) - matlab实现图割算法中的最大流最小割Max-flow/min-cut问题(一) 一)准备之前 对于一副图像分割之前,需要确定分割成几类,这里以灰度图像为例(彩色图像略复杂),通常来说分割成几类只有两种情况:事先知道该分成几类或者实现不知道该分成几类(这就是自适应分割了).该工具箱应该是对于事先知不知道几类的都可以处理,对

HDU 3435 A new Graph Game(最小费用流:有向环权值最小覆盖)

http://acm.hdu.edu.cn/showproblem.php?pid=3435 题意:有n个点和m条边,你可以删去任意条边,使得所有点在一个哈密顿路径上,路径的权值得最小. 思路: 费用流,注意判断重边,否则会超时. 1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<queue> 6 using names

HDU 1249 三角形的分割

可以将三角形的三条边一条一条加进图形中观察 假设添加第n个三角形 前n-1个三角形将区域划分为sum[n-1] 第n个三角形每条边最多能经过前n-1个三角形每条三角形的两条边 , 一条边切完增加了 2*(n-1)-1个区域 那么三条边切完内部图形增加了6*(n-1)-3个区域,而新三角形本身在三个顶角形成了三个新的区域 就共增加了6*(n-1)个区域 那么递推函数就是 sum[i] = sum[i-1] + 6*(i-1) 其实说的直接点就是利用欧拉公式解决问题 V(点) - E(边) + F(

HDU 3435 KM A new Graph Game

和HDU 3488一样的,只不过要判断一下是否有解. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 8 const int maxn = 1000 + 10; 9 const int INF = 0x3f3f3f3f; 10 11 i

HDU 3435 费用流

点击打开链接 题意:给个无向的图,问你删除任意边后,使这个图是哈密顿图,若有多个,输出路径上的所有权值和最小,没有就输出NO 思路:今天开始从10年多校开始刷题,敌人留给我们的时间不多了,这题看完题意后,看了看样例,自己yy了一下,写了一发,交了ac,看了样例后我是这样想的,因为是哈密顿图,那么每个点肯定是走了两次,而图是无向图,和求最大匹配有些类似,然后就瞎YY的过了 #include <queue> #include <vector> #include <stdio.h&

2015ACM/ICPC Asia Regional Changchun Online /HDU 5438 图

Ponds                                   Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)                                        Problem Description Betty owns a lot of ponds, some of them are connected with other

hdu 3966 树链分割第一3遍

真的不好意思说话.你写得越多,对风暴各种问题泄露,更离谱,有什么错有.. .但是,仍然有一个.同时经过规范的编写清晰的代码.不能认为是理所当然... 树桩阵列版: #include<cstdio> #include<cstring> #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<algorithm> using nam