题意:

  给你一个带权有向图,选择一些边组成许多没有公共边的环,使每个点都在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 & 拆点分环费用流的更多相关文章

  1. hdu 1853(拆点判环+费用流)

    Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others)Total ...

  2. 洛谷 P2045 方格取数加强版【费用流】

        题目链接:https://www.luogu.org/problemnew/show/P2045 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现 ...

  3. 洛谷 P1251 餐巾计划问题(线性规划网络优化)【费用流】

    (题外话:心塞...大部分时间都在debug,拆点忘记加N,总边数算错,数据类型标错,字母写错......) 题目链接:https://www.luogu.org/problemnew/show/P1 ...

  4. Acme Corporation UVA - 11613 拆点法+最大费用最大流(费用取相反数)+费用有正负

    /** 题目:Acme Corporation UVA - 11613 拆点法+最大费用最大流(费用取相反数)+费用有正负 链接:https://vjudge.net/problem/UVA-1161 ...

  5. 【 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 ...

  6. POJ 2175 Evacuation Plan (费用流,负环,消圈法,SPFA)

    http://poj.org/problem?id=2175 Evacuation Plan Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  7. CF 277E Binary Tree on Plane (拆点 + 费用流) (KM也可做)

    题目大意: 平面上有n个点,两两不同.现在给出二叉树的定义,要求树边一定是从上指向下,即从y坐标大的点指向小的点,并且每个结点至多有两个儿子.现在让你求给出的这些点是否能构成一棵二叉树,如果能,使二叉 ...

  8. HDU 4780 Candy Factory(拆点费用流)

    Problem Description   A new candy factory opens in pku-town. The factory import M machines to produc ...

  9. BZOJ 1877 晨跑 拆点费用流

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1877 题目大意: Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧 ...

随机推荐

  1. 2.2 顺序容器-list

    list(双向链表) 1) *  :包含头文件list **:不支持随机存取:增删元素时间是常数,只需要修改指针 2)成员函数 *  :vector的成员函数list基本都有 **:以下是部分独有成员 ...

  2. jdbc连接oracle数据库

    /*** 通过改变配置文件来连接不同数据库*/package com.xykj.jdbc; import static org.junit.Assert.*; import java.io.Input ...

  3. Java中length,length(),size()区别

    length属性:用于获取数组长度. eg: int ar[] = new int{1,2,3} /** * 数组用length属性取得长度 */ int lenAr = ar.length;//此处 ...

  4. Faster-rnnlm代码分析1 - 词表构建,Nnet成员

    https://github.com/yandex/faster-rnnlm     Gdb ./rnnlm r -rnnlm model-good.faster -train thread.titl ...

  5. OCJP(1Z0-851) 模拟题分析(四)over

    Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有 ...

  6. static_cast、dynamic_cast、reinterpret_cast、const_cast以及C强制类型转换的区别

    static_cast 1. 基础类型之间互转.如:float转成int.int转成unsigned int等 2. 指针与void*之间互转.如:float*转成void*.CBase*转成void ...

  7. c++ 调用dll

    1.首先写一个dll程序并且输出成dll. 新建win32项目,然后在应用程序类型中选择dll. HelloDll.h: #pragma once #ifndef MYDLL_API_EXPORTS ...

  8. hibernate查询语句实例代码

    一.聚集函数的使用: avg(...), sum(...), min(...), max(...) count(*) count(...), count(distinct ...), count(al ...

  9. [Tools] 使用XP远程登录Win8系统

    [背景] 完成最基本的设置后,发现xp依然不能远程访问win8桌面,搜索后发现需要进一步设置   [开工] 按照参考资料进行设置,下面的参考资料已经写的很详细了,只是参考资料2中的文件名: redss ...

  10. 免费电子书:C#代码整洁之道

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:<Clean Code(代码整洁之道)>是一本经典的著作,那么对于编写整洁 ...