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最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧 ...
随机推荐
- NYOJ题目845无主之地1
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAskAAAKbCAIAAACIEYBGAAAgAElEQVR4nO3dvXKkPLe38X0Szn0gjv
- 1.4 算法 - algorithm
1)概述 2)示例 //algorithm find演示 #include <vector> #include <algorithm> #include <iostrea ...
- 红外解码编码学习----verilog
在设计中运用红外遥控器可以很好的解决按键缺少的问题,还可以方便的控制产品. 红外发射部分: 红外发射管: 判断红外发射管的好坏 : 电路原理图: 接收部分: 传输的NEC协议: 本实验电路: veri ...
- Java的位运算符详解实例——与(&)、非(~)、或(|)、异或(^)
位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面 ...
- tomcat安装服务和内存参数设置
第一:安装服务 在dos窗口进入到tomcat的bin目录下,通过如下命令即可将tomcat安装成服务 service.bat install Tomcat2 其中Tomcat2是服务的名称 如果启动 ...
- poj 2524:Ubiquitous Religions(并查集,入门题)
Ubiquitous Religions Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 23997 Accepted: ...
- Power BI中的QA功能预览
微软在休斯敦的全球合作伙伴大会上发布了Power BI for Office 365,通过Excel和Office 365中的自服务式商业智能解决方案为信息工作者提供了数据分析以及可视化功能以帮助他们 ...
- JAVA 堆栈知识和Volatile关键字
栈内存:存放基本类型的变量和对象的引用 堆内存:存放用new创建的对象和数组 栈帧:保存了局部变量表,操作数栈,方法的返回地址以及其它的附加信息 volatile修饰的变量,jvm虚拟机只是保证从主内 ...
- yaf框架使用(centos6.5)
安装好php环境之后 安装扩展包 $yum install php-devel /usr/bin/ 就会出现phpize工具包 下载yaf-2.2.8.gz源文件,解压后,进入源文件 phpize [ ...
- golang基础知识之encoding/json package
golang基础知识之json 简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式.可以去json.org 查看json标准的清晰定义.json pack ...