• [AHOI2008]上学路线


    嘟嘟嘟

    这道题其实挺显然的。

    首先dijkstra跑出最短路图,然后在最短路图上求最小割。

    正确性显然。

    需要注意的是,在新图中添加最短路图的边的时候,一定是跑完dijkstra再加边,如果边跑dijkstra边加边,得到的是最短路树,而不是。我因为这个WA了好几发。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<vector>
      9 #include<stack>
     10 #include<queue>
     11 using namespace std;
     12 #define enter puts("") 
     13 #define space putchar(' ')
     14 #define Mem(a, x) memset(a, x, sizeof(a))
     15 #define rg register
     16 typedef long long ll;
     17 typedef double db;
     18 const int INF = 0x3f3f3f3f;
     19 const db eps = 1e-8;
     20 const int maxn = 505;
     21 const int maxe = 1.3e5 + 5;
     22 inline ll read()
     23 {
     24   ll ans = 0;
     25   char ch = getchar(), last = ' ';
     26   while(!isdigit(ch)) {last = ch; ch = getchar();}
     27   while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
     28   if(last == '-') ans = -ans;
     29   return ans;
     30 }
     31 inline void write(ll x)
     32 {
     33   if(x < 0) x = -x, putchar('-');
     34   if(x >= 10) write(x / 10);
     35   putchar(x % 10 + '0');
     36 }
     37 
     38 int n, m;
     39 struct Edge1
     40 {
     41   int nxt, to, t, c;
     42 }e1[maxe << 1];
     43 int head1[maxn], ecnt1 = -1;
     44 void addEdge1(int x, int y, int t, int c)
     45 {
     46   e1[++ecnt1] = (Edge1){head1[x], y, t, c};
     47   head1[x] = ecnt1;
     48 }
     49 
     50 struct Edge2
     51 {
     52   int nxt, from, to, cap, flow;
     53 }e2[maxe << 2];
     54 int head2[maxn], ecnt2 = -1;
     55 void addEdge2(int from, int to, int w)
     56 {
     57   e2[++ecnt2] = (Edge2){head2[from], from, to, w, 0};
     58   head2[from] = ecnt2;
     59   e2[++ecnt2] = (Edge2){head2[to], to, from, 0, 0};
     60   head2[to] = ecnt2;
     61 }
     62 
     63 #define pr pair<int, int>
     64 #define mp make_pair
     65 bool in[maxn];
     66 int dis[maxn];
     67 void dijkstra(int s)
     68 {
     69   Mem(dis, 0x3f); dis[s] = 0;
     70   priority_queue<pr, vector<pr>, greater<pr> > q;
     71   q.push(mp(dis[s], s));
     72   while(!q.empty())
     73     {
     74       int now = q.top().second; q.pop();
     75       if(in[now]) continue;
     76       in[now] = 1;
     77       for(int i = head1[now]; i != -1; i = e1[i].nxt)
     78     {
     79       if(dis[e1[i].to] > dis[now] + e1[i].t)
     80         {
     81           dis[e1[i].to] = dis[now] + e1[i].t;
     82           q.push(mp(dis[e1[i].to], e1[i].to));
     83         }
     84     }
     85     }
     86 }
     87 
     88 int dis2[maxn];
     89 bool bfs()
     90 {
     91   Mem(dis2, 0); dis2[1] = 1;
     92   queue<int> q; q.push(1);
     93   while(!q.empty())
     94     {
     95       int now = q.front(); q.pop();
     96       for(int i = head2[now]; i != -1; i = e2[i].nxt)
     97     {
     98       if(!dis2[e2[i].to] && e2[i].cap > e2[i].flow)
     99         {
    100           dis2[e2[i].to] = dis2[now] + 1;
    101           q.push(e2[i].to);
    102         }
    103     }
    104     }
    105   return dis2[n];
    106 }
    107 int cur[maxn];
    108 int dfs(int now, int res)
    109 {
    110   if(now == n || res == 0) return res;
    111   int flow = 0, f;
    112   for(int &i = cur[now]; i != -1; i = e2[i].nxt)
    113     {
    114       if(dis2[e2[i].to] == dis2[now] + 1 && (f = dfs(e2[i].to, min(res, e2[i].cap - e2[i].flow))) > 0)
    115     {
    116       e2[i].flow += f; e2[i ^ 1].flow -= f;
    117       flow += f; res -= f;
    118       if(res == 0) break;
    119     }
    120     }
    121   return flow;
    122 }
    123 
    124 int minCut()
    125 {
    126   int flow = 0;
    127   while(bfs())
    128     {
    129       memcpy(cur, head2, sizeof(head2));
    130       flow += dfs(1, INF);
    131     }
    132   return flow;
    133 }
    134 
    135 int main()
    136 {
    137   Mem(head1, -1); Mem(head2, -1);
    138   n = read(); m = read();
    139   for(int i = 1; i <= m; ++i)
    140     {
    141       int x = read(), y = read(), t = read(), c = read();
    142       addEdge1(x, y, t, c); addEdge1(y, x, t, c);
    143     }
    144   dijkstra(1);
    145   for(int i = 1; i <= n; ++i)
    146     for(int j = head1[i]; j != -1; j = e1[j].nxt)
    147       if(dis[e1[j].to] == dis[i] + e1[j].t) addEdge2(i, e1[j].to, e1[j].c);
    148   write(dis[n]), enter, write(minCut()), enter;
    149   return 0;
    150 }
    View Code
  • 相关阅读:
    commons-logging.jar 和 log4j.jar 的关系
    百钱买百鸡
    reflect
    golang结构体、接口、反射
    golang文件操作
    sqlx使用说明
    go example
    goroutine
    生成二维码
    method&interface
  • 原文地址:https://www.cnblogs.com/mrclr/p/9841947.html
Copyright © 2020-2023  润新知