UVa 2197 & 拆点分环费用流
题意:
给你一个带权有向图,选择一些边组成许多没有公共边的环,使每个点都在k个环上,要求代价最小。
SOL:
现在已经养成了这种习惯,偏题怪题都往网络流上想。。。
怎么做这题呢。。。
对我们看到每个点都在k个环上,而且没有公共边,那么很显然每个点的入度出度都为k. 然后我们拆点,建源汇ST,S与每个入点连边容量为k,出点与汇点相连容量为k,费用为0,如果城市i,j之间有边那么将i的入点和j的出点连一条费用为权,容量为1的边.然后跑一遍费用流.如果每条边都满流那么就有解.
好神奇...从环变成一个二分图...然后从毫无头绪变成一个费用流...又觉得智商被碾压了.
写代码因为spfa的时候出队结点没重置...然后一直wa...日了狗了...
更加理解spfa了....(无奈
Code:
/*==========================================================================
# Last modified: 2016-03-10 20:55
# Filename: uva2197.cpp
# Description:
==========================================================================*/
#define me AcrossTheSky
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> #include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector> #define lowbit(x) (x)&(-x)
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define getlc(a) ch[(a)][0]
#define getrc(a) ch[(a)][1] #define maxn 100000
#define maxm 100000
#define pi 3.1415926535898
#define _e 2.718281828459
#define INF 1070000000
using namespace std;
typedef long long ll;
typedef unsigned long long ull; template<class T> inline
void read(T& num) {
bool start=false,neg=false;
char c;
num=0;
while((c=getchar())!=EOF) {
if(c=='-') start=neg=true;
else if(c>='0' && c<='9') {
start=true;
num=num*10+c-'0';
} else if(start) break;
}
if(neg) num=-num;
}
/*==================split line==================*/
struct Edge{
int from,to,c,cap;
}e[maxm];
int dis[maxn],first[maxn],next[maxm],from[maxn];
bool inq[maxn];
int sume,n,m,k,S,T,f,ans;
void addedge(int x,int y,int c,int cap){
sume++; e[sume].from=x; e[sume].to=y; e[sume].c=c; e[sume].cap=cap;
next[sume]=first[x]; first[x]=sume;
sume++; e[sume].from=y; e[sume].to=x; e[sume].c=-c; e[sume].cap=0;
next[sume]=first[y]; first[y]=sume;
}
bool spfa(){
FORP(i,S,T) dis[i]=INF;
memset(inq,false,sizeof(inq));
queue<int> q;
dis[S]=0; inq[S]=true; q.push(S);
while (!q.empty()){
int now=q.front(); q.pop(); inq[now]=false;
for (int i=first[now];i;i=next[i])
if (dis[e[i].to]>dis[now]+e[i].c && e[i].cap){
dis[e[i].to]=dis[now]+e[i].c; from[e[i].to]=i;
if (!inq[e[i].to]){
inq[e[i].to]=true;
q.push(e[i].to);
}
}
}
return dis[T]==INF?false:true;
}
void mincost(){
int i=from[T],x=INF;
while (i){
x=min(x,e[i].cap);
i=from[e[i].from];
}
f+=x; i=from[T];
while (i){
//ans+=(x*e[i].c);
e[i].cap-=x; e[i^1].cap+=x;
i=from[e[i].from];
}
ans+=dis[T]*x;
}
void init(){
ans=0; memset(first,0,sizeof(first));
f=0; sume=1;
read(n); read(m); read(k);
S=0; T=n+n+2;
FORP(i,1,n) {
addedge(S,i,0,k); addedge(i+n,T,0,k);
}
//FORP(i,1,n) addedge(i,i+n,
FORP(i,1,m){
int u,v,w;
read(u);read(v);read(w);
u++; v++;
addedge(u,v+n,w,1);
}
}
void work(){
int ans=0;
while (spfa()) mincost();
}
void print(){
bool flag=true;
//FORP(i,2,sume) if (e[i].cap>0) {flag=false; break;}
if (f<n*k) flag=false;
if (!flag) printf("-1\n");
else printf("%d\n",ans);
}
int main(){
int cas; read(cas);
while (cas--){
init();
work();
print();
}
}
UVa 2197 & 拆点分环费用流的更多相关文章
- hdu 1853(拆点判环+费用流)
Cyclic Tour Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/65535 K (Java/Others)Total ...
- 洛谷 P2045 方格取数加强版【费用流】
题目链接:https://www.luogu.org/problemnew/show/P2045 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现 ...
- 洛谷 P1251 餐巾计划问题(线性规划网络优化)【费用流】
(题外话:心塞...大部分时间都在debug,拆点忘记加N,总边数算错,数据类型标错,字母写错......) 题目链接:https://www.luogu.org/problemnew/show/P1 ...
- Acme Corporation UVA - 11613 拆点法+最大费用最大流(费用取相反数)+费用有正负
/** 题目:Acme Corporation UVA - 11613 拆点法+最大费用最大流(费用取相反数)+费用有正负 链接:https://vjudge.net/problem/UVA-1161 ...
- 【 UVALive - 2197】Paint the Roads(上下界费用流)
Description In a country there are n cities connected by m one way roads. You can paint any of these ...
- POJ 2175 Evacuation Plan (费用流,负环,消圈法,SPFA)
http://poj.org/problem?id=2175 Evacuation Plan Time Limit: 1000MS Memory Limit: 65536K Total Submi ...
- CF 277E Binary Tree on Plane (拆点 + 费用流) (KM也可做)
题目大意: 平面上有n个点,两两不同.现在给出二叉树的定义,要求树边一定是从上指向下,即从y坐标大的点指向小的点,并且每个结点至多有两个儿子.现在让你求给出的这些点是否能构成一棵二叉树,如果能,使二叉 ...
- HDU 4780 Candy Factory(拆点费用流)
Problem Description A new candy factory opens in pku-town. The factory import M machines to produc ...
- BZOJ 1877 晨跑 拆点费用流
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1877 题目大意: Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧 ...
随机推荐
- C#的lock关键字
using System; using System.Threading; namespace Test { class Program { //一.Lock定义 //lock 关键字可以用来确保代码 ...
- PHP实现执行定时任务的几种思路详解
转:https://segmentfault.com/a/1190000002955509 PHP本身是没有定时功能的,PHP也不能多线程.PHP的定时任务功能必须通过和其他工具结合才能实现,例如Wo ...
- JavaScript 火花效果
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- MySql中delimiter的作用是什么?
这个命令与存储过程没什么关系吧.其实就是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执行了.默认情况下,delimiter是分号;.在命令行客户端中,如果有一行命令以分号结束,那么 ...
- 【openGL】画圆
#include "stdafx.h" #include <GL/glut.h> #include <stdlib.h> #include <math ...
- 攻城狮在路上(壹) Hibernate(十七)--- Hibernate并发处理问题
一.多个事务并发运行时的并发问题: 总结为第一类丢失更新.脏读.虚读.不可重复读.第二类丢失更新. 1.第一类丢失更新: 撤销一个事务时,把其他事务已提交的更新数据覆盖. 2.脏读: 一个事务读到另一 ...
- [Eclipse][SVN] 在eclipse上安装SVN
以前装过好多次SVN,始终没有一次把安装过程记录下来,这次新装机器,安装SVN插件时一波三折,记录下来免得以后又忘记了. 方法一: 1. 直接通过后台添加URL通过互联网进行安装,直接上图: 2. ...
- [荐]js模版引擎handlebars.js
[官方介绍:http://handlebarsjs.com/] Handlebars provides the power necessary to let you build semantic te ...
- 高效jQuery的奥秘
讨论jQuery和javascript性能的文章并不罕见.然而,本文我计划总结一些速度方面的技巧和我本人的一些建议,来提升你的jQuery和javascript代码.好的代码会带来速度的提升.快速渲染 ...
- codeforces 45C C. Dancing Lessons STL
C. Dancing Lessons There are n people taking dancing lessons. Every person is characterized by his ...