poj 2455

来源:互联网 发布:网络问卷调查怎么弄 编辑:程序博客网 时间:2024/05/01 03:19

说实话我都不知道为什么要写这题题解。毕竟代码都不是我写的,

思路很好想 二分+网络流判定可行性,这个想到了。

然后决定学习dinic

所以当个备忘录,明天求教

#include <iostream>  #include <cstdio>  #include <cstring>  #include <algorithm>  #include <queue>  using namespace std;  const int N = 210;  const int INF = 0x3f3f3f3f;  struct edge  {      int to, cap, next;  }g[N*1000];  int head[N], iter[N], level[N], d[N*400][3];  int cnt;  void add_edge(int v, int u, int cap)  {      g[cnt].to = u, g[cnt].cap = cap, g[cnt].next = head[v], head[v] = cnt++;      g[cnt].to = v, g[cnt].cap = cap, g[cnt].next = head[u], head[u] = cnt++; //无向图时反向边容量不为0  }  bool bfs(int s, int t)  {      memset(level, -1, sizeof level);      queue<int> que;      level[s] = 0;      que.push(s);      while(! que.empty())      {          int v = que.front(); que.pop();          for(int i = head[v]; i != -1; i = g[i].next)          {              int u = g[i].to;              if(g[i].cap > 0 && level[u] < 0)              {                  level[u] = level[v] + 1;                  que.push(u);              }          }      }      return level[t] == -1;  }  int dfs(int v, int t, int f)  {      if(v == t) return f;      for(int &i = iter[v]; i != -1; i = g[i].next)      {          int u = g[i].to;          if(g[i].cap > 0 && level[v] < level[u])          {              int d = dfs(u, t, min(f, g[i].cap));              if(d > 0)              {                  g[i].cap -= d, g[i^1].cap += d;                  return d;              }          }      }      return 0;  }  int dinic(int s, int t)  {      int flow = 0, f;      while(true)      {          if(bfs(s, t)) return flow;          memcpy(iter, head, sizeof head);          while(f = dfs(s, t, INF), f > 0)              flow += f;      }  }  int main()  {      int n, p, t;      while(~ scanf("%d%d%d", &n, &p, &t))      {          int maxx = -1, minn = INF;          for(int i = 0; i < p; i++)          {              scanf("%d%d%d", &d[i][0], &d[i][1], &d[i][2]);              maxx = max(maxx, d[i][2]);              minn = min(minn, d[i][2]);          }          int l = minn, r = maxx, res;          while(l <= r)          {              int mid = (l + r) >> 1;              cnt = 0;              memset(head, -1, sizeof head);              for(int i = 0; i < p; i++)                  if(d[i][2] <= mid)                      add_edge(d[i][0], d[i][1], 1);              if(dinic(1, n) >= t) r = mid - 1, res = mid;              else l = mid + 1;          }          printf("%d\n", res);      }      return 0;  } 
0 0
原创粉丝点击