您的位置:首页 > 其它

hdu 5294 Tricks Device

2015-07-22 15:14 337 查看
题意:

最少破坏多少条路,所有的最短路都无法走通。

最多破环多少条路,任然有一条最短路可以走。

分析:对于第二个问题,求出最短路路径数最小的一条即可,第一个问题,用最短路径上所有的边构建网络,然后求出最大流即为所求,因为这题边很多,所以用EK会超时,换成dinic就能AC。

ps:构建网络写的太乱了,不过好歹A了,需要好好整理一下,写一个更清晰的版本。

以下附上代码:

#include <algorithm>
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cctype>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int maxn = 2005;
const int maxm = 600005;
const int inf = 1000000000;

int n,m;

struct Node{
int v,w;
int c,f;
int next;
bool use;
};

struct Adlist{
int vex[maxn];
Node arc[maxm*2];
int cnt;

void Clear(){
for(int i = 0; i <= n; i++){
vex[i] = -1;
}
cnt = 0;
}

void Insert(int u, int v, int w){
arc[cnt].v = v;
arc[cnt].w = w;
arc[cnt].next = vex[u];
arc[cnt].use = 0;
vex[u] = cnt;
++cnt;
}

void Insert(int u, int v){
arc[cnt].v = v;
arc[cnt].c = 1;
arc[cnt].f = 0;
arc[cnt].next = vex[u];
arc[cnt].use = 0;
vex[u] = cnt;
++cnt;
}

void Augment(int u, int v, int flow){
for(int i = vex[u]; i != -1; i = arc[i].next){
if(arc[i].v == v && arc[i].f < arc[i].c && arc[i].f + flow < arc[i].c && arc[i].f + flow >= 0){
arc[i].f += flow;
return;
}
}
}

int Have(int u, int v){
for(int i = vex[u]; i != -1; i = arc[i].next){
if(arc[i].v == v && !arc[i].use){
return i;
}
}
return -1;
}
};

Adlist e;
Adlist Network;
//for spfa
queue<int> q;
int low[maxn];
vector<int> path[maxn];//记录所有路径
int cnt[maxn];//到每个点的最短路径有多少种走法
//for maxFlow
int vis[maxn];
int d[maxn];//层次网路

void input()
{
int u,v,w;
e.Clear();
for(int i = 0; i < m; i++){
scanf("%d%d%d",&u,&v,&w);
e.Insert(u,v,w);
e.Insert(v,u,w);
}
}

void spfa(int s)
{
for(int i = 0; i <= n; i++) low[i] = inf;
low[s] = 0,cnt[s] = 0;
path[s].clear();
q.push(s);

int u,v;
while(!q.empty()){
u = q.front(); q.pop();
for(int i = e.vex[u]; i != -1; i = e.arc[i].next){
v = e.arc[i].v;
if(low[u] + e.arc[i].w < low[v]){
low[v] = low[u] + e.arc[i].w;
cnt[v] = cnt[u] + 1;

path[v].clear();
path[v].push_back(u);
q.push(v);

}
else if(low[u] + e.arc[i].w == low[v]){
cnt[v] = min(cnt[v],cnt[u]+1);
path[v].push_back(u);
}
}
}
if(low
== inf) cnt
= 0;

}

void build(int t)//构建网络
{
int u,v;
int pos;
for(int i = 0; i < path[t].size(); i++){
u = path[t][i]; v = t;
pos = e.Have(u,v);
if(pos != -1){
Network.Insert(u,v);
e.arc[pos].use = 1;
}
build(u);
}
}

void print()//
{

int u,v;
for(int i = 1; i <= n; i++){
u = i;
cout << u << " : ";
for(int j = Network.vex[i]; j != -1; j = Network.arc[j].next){
v = Network.arc[j].v;
cout << v << " " << Network.arc[j].f << " f ";
}
cout << endl;
}
}

int bfs()//bfs构建层次网络
{
fill(vis,vis+n+1,0);

q.push(1);
d[1] = 0;
vis[1] = 1;

int u,v;
while(!q.empty()){
u = q.front(); q.pop();

for(int i = Network.vex[u]; i != -1; i = Network.arc[i].next){
v = Network.arc[i].v;
if(!vis[v] && Network.arc[i].f < Network.arc[i].c){//
vis[v] = 1;
d[v] = d[u] + 1;
q.push(v) ;
}
}
}
return vis
;

}

int dfs(int u, int alpha)//dinic
{
if(u == n || alpha == 0) return alpha;
int v;
int sum = 0;
for(int i = Network.vex[u]; i != -1; i = Network.arc[i].next){
v = Network.arc[i].v;
int flow;
if(d[v] == d[u] + 1){
flow = dfs(v,min(alpha-sum,Network.arc[i].c-Network.arc[i].f));
if(flow > 0){
Network.arc[i].f += flow;
Network.Augment(v,u,-flow);
sum += flow;
if(sum == alpha) break;
}
}

}
return sum;
}

int maxFlow()//求最大流
{
int maximum = 0;
int flow;
while(bfs()){
fill(vis,vis+n+1,0);
maximum += dfs(1,inf);
}
return maximum;
}

int main()
{
while(scanf("%d%d",&n,&m) != EOF){
input();
spfa(1);
Network.Clear();
build(n);
printf("%d %d\n",maxFlow(),m-cnt
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: