题目大意:一个有源有汇的城市,问最少增加城市中的多少道路可以增加源到汇上各个路径上可容纳的总车流量增加。

网络流关键割边集合指如果该边的容量增加,整个网络流图中的任意从原点到汇点的路径的流量便可增加。

从源点开始遍历未满流的边,这些边两端节点的集合称为S;同理再从汇点开始遍历,集合称为T;其余的点组成另一个集合。如果一个边是最小割,则其两端属于不同的集合。如果一个边是关键割边,则该边两端节点一个属于S,一个属于T。遍历每一个图中的边,看它是否满足该条件即可。

#include <cstdio>
#include <cstring>
#include <cassert>
#include <cmath>
#include <algorithm>
using namespace std; const int NODE_MAX = 1100, EDGE_MAX = 10100, INF = 0x3f3f3f3f; //below:for dinic-----------------------------------------------------
struct Node;
struct Edge; struct Node
{
int Id, Vis;
int Level;
Edge *Head;
}; struct Edge
{
int Cap, Id;
Edge* Rev, *Next;
Node *From, *To;
}; Node _nodes[NODE_MAX];
Edge _edges[EDGE_MAX];
int _lastVId, _eCount = 0;
Node *StartNode, *TargetNode; void Init()
{
memset(_nodes, 0, sizeof(_nodes));
memset(_edges, 0, sizeof(_edges));
_eCount = 0;
} Edge *NewEdge()
{
return ++_eCount + _edges;
} void SetST(int sId, int tId)
{
StartNode = _nodes + sId;
TargetNode = _nodes + tId;
} void SetLastVId(int vId)
{
_lastVId = vId;
} Edge *AddEdge(Node *from, Node *to, int id, int cap)
{
Edge *e = NewEdge();
e->Id = id;
e->From = from;
e->To = to;
e->Cap = cap;
e->Next = e->From->Head;
e->From->Head = e;
return e;
} void Build(int uId, int vId, int id, int cap)
{
Node *u = uId + _nodes, *v = vId + _nodes;
u->Id = uId;
v->Id = vId;
Edge *e1 = AddEdge(u, v, id, cap);
Edge *e2 = AddEdge(v, u, -id, 0);
e1->Rev = e2;
e2->Rev = e1;
} struct NodeQueue
{
Node *q[NODE_MAX];
int head, tail;
void clear() { head = tail = 0; }
void push(Node *v) { q[tail++] = v; }
Node* front() { return q[head]; }
void pop() { head++; }
bool empty() { return head == tail; }
}; bool Bfs()
{
for (int i = 0; i <= _lastVId; i++)
_nodes[i].Level = 0;
NodeQueue q;
q.clear();
StartNode->Level = 1;
q.push(StartNode);
while (!q.empty())
{
Node *cur = q.front();
q.pop();
for (Edge *e = cur->Head; e; e = e->Next)
{
if (!e->To->Level && e->Cap)
{
e->To->Level = cur->Level + 1;
q.push(e->To);
}
}
}
return TargetNode->Level;
} int Dfs(Node *cur, int limit)
{
if (cur == TargetNode)
return limit;
if (limit == 0)
return 0;
int curTake = 0;
for (Edge *e = cur->Head; e; e = e->Next)
{
if (e->To->Level == cur->Level + 1 && e->Cap)
{
int nextTake = Dfs(e->To, min(limit - curTake, e->Cap));
e->Cap -= nextTake;
e->Rev->Cap += nextTake;
curTake += nextTake;
}
}
return curTake;
} int Dinic()
{
int ans = 0;
while (Bfs())
ans += Dfs(StartNode, INF);
return ans;
}
//above:for dinic----------------------------------------------------- void Dfs1(Node *cur)
{
assert(!cur->Vis);
cur->Vis = 1;
for (Edge *e = cur->Head; e; e = e->Next)
if (e->Cap && !e->To->Vis && e->Id > 0)
Dfs1(e->To);
} void Dfs2(Node *cur)
{
assert(cur->Vis != 1);
cur->Vis = 2;
for (Edge *e = cur->Head; e; e = e->Next)
if (e->Rev->Cap && !e->To->Vis &&e->Rev->Id > 0)
Dfs2(e->To);
} int main()
{
freopen("c:\\noi\\source\\input.txt", "r", stdin);
int totCity, totEdge;
scanf("%d%d", &totCity,&totEdge);
Init();
SetLastVId(totCity - 1);
SetST(0, totCity - 1);
int uId, vId, cap;
for (int i = 1; i <= totEdge; i++)
{
scanf("%d%d%d", &uId, &vId, &cap);
Build(uId, vId, i, cap);
}
Dinic();
Dfs1(StartNode);
Dfs2(TargetNode);
int eId[EDGE_MAX], pe = 0;
memset(eId, 0, sizeof(eId));
for (int i = 1; i <= _eCount; i++)
if (_edges[i].From->Vis == 1 && _edges[i].To->Vis == 2 && _edges[i].Id > 0)
eId[pe++] = _edges[i].Id;
sort(eId, eId + pe);
printf("%d\n", pe);
return 0;
}

  

最新文章

  1. C++新特性(类)(转载)
  2. Interview Question
  3. 学习练习 java产生6个不同的数字
  4. Linux显示全部执行中的进程
  5. C语言的面向对象设计 —— 对 X264/FFMPEG 架构探讨
  6. 一个Shell小脚本——旋转的斜杠
  7. SDN网络虚拟化中有效协调的映射算法
  8. Python+自动化测试框架的设计编写
  9. PhpStorm的注册激活方法
  10. qml: 打包 和 发布
  11. Springboot+Mybatis 显示sql语句
  12. go build 和 go install
  13. iOS NSUserDefaults
  14. effective c++ 笔记 (31-34)
  15. Asp.Net Core WebAPI入门整理(二)简单示例
  16. poj 1988 并查集(终于看懂一个了/(ㄒoㄒ)/~~)
  17. gpio子系统和pinctrl子系统(中)
  18. C# 在类文件自动添加文件注释的方法
  19. C# XML对象序列化、反序列化 - PEPE YU
  20. Spring-@value用法详解

热门文章

  1. MySQL 数据的增删改查
  2. mybatis 传map参数
  3. 安装完MongoDB后尝试mongod -dbpath命令为什么会一直卡在连接端口?
  4. Oracle存储过程给变量赋值的方法
  5. 时序分析:串匹配-KMP算法
  6. 将 GNOME 默认的界面切换动画功能关闭
  7. 团体程序设计天梯赛-练习集-L1-032. Left-pad
  8. javaee IO流作业02
  9. Docker拉取images时报错Error response from daemon
  10. TeX中的引号(Tex Quotes, UVa 272)