zoukankan      html  css  js  c++  java
  • bzoj 1266: [AHOI2006]上学路线route

    思路:找出最短路图, 然后求最小割。

      1 #include<bits/stdc++.h>
      2 #define LL long long
      3  
      4 using namespace std;
      5  
      6 const int N = 507;
      7 const int M = 124750;
      8 const int inf = 0x3f3f3f3f;
      9  
     10 struct Edge {
     11     int u, v, t, c, nx;
     12 } edge[2][M << 1];
     13  
     14 int n, m, S, T, tot[2], head[2][N], d[N], in[N], level[N];
     15  
     16 void add(int x, int u, int v, int t, int c) {
     17     edge[x][tot[x]].u = u;
     18     edge[x][tot[x]].v = v;
     19     edge[x][tot[x]].t = t;
     20     edge[x][tot[x]].c = c;
     21     edge[x][tot[x]].nx = head[x][u];
     22     head[x][u] = tot[x]++;
     23 }
     24  
     25 void spfa() {
     26     queue<int> que;
     27     d[1] = 0; que.push(1); in[1] = 1;
     28     while(!que.empty()) {
     29         int u = que.front(); que.pop();
     30         for(int i = head[0][u]; ~i; i = edge[0][i].nx) {
     31             int v = edge[0][i].v, t = edge[0][i].t;
     32             if(d[u] + t < d[v]) {
     33                 d[v] = d[u] + t;
     34                 if(!in[v]) que.push(v);
     35             }
     36         }
     37         in[u] = 0;
     38     }
     39 }
     40  
     41 bool bfs() {
     42     memset(level, 0, sizeof(level));
     43     queue<int> que;
     44     que.push(S); level[S] = 1;
     45     while(!que.empty()) {
     46         int u = que.front(); que.pop();
     47         if(u == T) return true;
     48         for(int i = head[1][u]; ~i; i = edge[1][i].nx) {
     49             int v = edge[1][i].v;
     50             if(!level[v] && edge[1][i].c > 0) {
     51                 que.push(v);
     52                 level[v] = level[u] + 1;
     53             }
     54         }
     55     }
     56     return false;
     57 }
     58  
     59 int dfs(int u, int p) {
     60     if(u == T) return p;
     61     int ret = 0;
     62     for(int i = head[1][u]; ~i; i = edge[1][i].nx) {
     63         int v = edge[1][i].v, c = edge[1][i].c;
     64         if(c <= 0 || level[v] != level[u] + 1) continue;
     65         int f = dfs(v, min(p - ret, c));
     66         ret += f;
     67         edge[1][i].c -= f;
     68         edge[1][i ^ 1].c += f;
     69         if(ret == p) break;
     70     }
     71     if(!ret) level[u] = 1;
     72     return ret;
     73 }
     74  
     75 int Dinic() {
     76     int ans = 0;
     77     while(bfs()) ans += dfs(S, inf);
     78     return ans;
     79 }
     80 int main() {
     81     memset(head, -1, sizeof(head));
     82     memset(d, inf, sizeof(d));
     83     scanf("%d%d", &n, &m);
     84     S = 1, T = n;
     85     for(int i = 1; i <= m; i++) {
     86         int u, v, t, c;
     87         scanf("%d%d%d%d", &u, &v, &t, &c);
     88         add(0, u, v, t, c);
     89         add(0, v, u, t, c);
     90     }
     91  
     92     spfa();
     93  
     94     for(int i = 0; i < tot[0]; i++) {
     95         int u = edge[0][i].u;
     96         int v = edge[0][i].v;
     97         int t = edge[0][i].t;
     98         int c = edge[0][i].c;
     99  
    100         if(d[u] + t == d[v]) {
    101             add(1, u, v, t, c);
    102             add(1, v, u, t, 0);
    103         }
    104     }
    105  
    106     int ans = Dinic();
    107  
    108     printf("%d
    ", d[n]);
    109     printf("%d
    ", ans);
    110     return 0;
    111 }
  • 相关阅读:
    返回一个整数数组中最大子数组的和(数组头尾连接)
    场景调研(补)
    《浪潮之巅》读书笔记3
    《软件工程》课程改进意见
    【每日scrum】第一次冲刺day6
    【每日scrum】第一次冲刺day5
    【每日scrum】第一次冲刺day4
    【每日scrum】第一次冲刺day3
    【每日scrum】第一次冲刺day2
    【每日scrum】第一次冲刺day1
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9092558.html
Copyright © 2011-2022 走看看