hdu 5294 Tricks Device

来源:互联网 发布:linux命令行上网 编辑:程序博客网 时间:2024/05/29 16:13

题意:

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

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


分析:对于第二个问题,求出最短路路径数最小的一条即可,第一个问题,用最短路径上所有的边构建网络,然后求出最大流即为所求,因为这题边很多,所以用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 spfaqueue<int> q;int low[maxn];vector<int> path[maxn];//记录所有路径 int cnt[maxn];//到每个点的最短路径有多少种走法 //for maxFlowint 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[n] == inf) cnt[n] = 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[n];  }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[n]);  }return 0;}


0 0
原创粉丝点击