• uva 1658 Admiral


    vjudge传送门[here]


      题目大意:给一个有(3≤v≤1000)个点e(3≤e≤10000)条边的有向加权图,求1~v的两条不相交(除了起点和终点外没有公共点)的路径,使权值和最小。

      正解是吧2到v-1的每个点拆成两个点,中间连一条容量为1,费用为0的边,然后求1到v的流量为2的最小费用流就行了。

    Code

      1 /**
      2  * Uva
      3  * Problem#1658
      4  * Accepted
      5  */
      6 #include<iostream>
      7 #include<cstdio>
      8 #include<cctype>
      9 #include<cstring>
     10 #include<cstdlib>
     11 #include<fstream>
     12 #include<sstream>
     13 #include<algorithm>
     14 #include<map>
     15 #include<set>
     16 #include<queue>
     17 #include<vector>
     18 #include<stack>
     19 using namespace std;
     20 typedef bool boolean;
     21 #define INF 0xfffffff
     22 #define smin(a, b) a = min(a, b)
     23 #define smax(a, b) a = max(a, b)
     24 template<typename T>
     25 inline boolean readInteger(T& u){
     26     char x;
     27     int aFlag = 1;
     28     while(!isdigit((x = getchar())) && x != '-' && ~x);
     29     if(x == -1){
     30         return false;
     31     }
     32     if(x == '-'){
     33         x = getchar();
     34         aFlag = -1;
     35     }
     36     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     37     ungetc(x, stdin);
     38     u *= aFlag;
     39     return true;
     40 }
     41 
     42 ///map template starts
     43 typedef class Edge{
     44     public:
     45         int end;
     46         int next;
     47         int cap;
     48         int flow;
     49         int cost;
     50         Edge(const int end = 0, const int next = 0, const int cap = 0, const int flow = 0, const int cost = 0):end(end), next(next), cap(cap), flow(flow), cost(cost){}
     51 }Edge;
     52 
     53 typedef class MapManager{
     54     public:
     55         int ce;
     56         int *h;
     57         Edge *edge;
     58         MapManager(){}
     59         MapManager(int points, int limit):ce(0){
     60             h = new int[(const int)(points + 1)];
     61             edge = new Edge[(const int)(limit + 1)];
     62             memset(h, 0, sizeof(int) * (points + 1));
     63         }
     64         inline void addEdge(int from, int end, int cap, int flow, int cost){
     65             edge[++ce] = Edge(end, h[from], cap, flow, cost);
     66             h[from] = ce;
     67         }
     68         inline void addDoubleEdge(int from, int end, int cap, int cost){
     69             addEdge(from, end, cap, 0, cost);
     70             addEdge(end, from, cap, cap, -cost);
     71         }
     72         Edge& operator [](int pos){
     73             return edge[pos];
     74         }
     75         inline int reverse(int pos){
     76             return (pos & 1) ? (pos + 1) : (pos - 1);
     77         }
     78         inline void clean(){
     79             delete[] h;
     80             delete[] edge;
     81             ce = 0;
     82         }
     83 }MapManager;
     84 #define m_begin(g, i) (g).h[(i)]
     85 /// map template ends
     86 
     87 int n, m;
     88 MapManager g;
     89 
     90 inline boolean init(){
     91     if(!readInteger(n))    return false;
     92     readInteger(m);
     93     g = MapManager(n * 2, m * 2 + n * 2);
     94     for(int i = 1, a, b, w; i <= m; i++){
     95         readInteger(a);
     96         readInteger(b);
     97         readInteger(w);
     98         g.addDoubleEdge(a + n, b, 1, w);
     99     }
    100     for(int i = 1; i <= n; i++){            //拆点 
    101         g.addDoubleEdge(i, i + n, 1, 0);
    102     }
    103     return true;
    104 }
    105 
    106 int* dis;
    107 boolean* visited;
    108 int* last;
    109 int* laste;
    110 int* mflow;
    111 int cost;
    112 int s, t;
    113 queue<int> que;
    114 int sizee;
    115 
    116 inline void spfa(){
    117     memset(dis, 0x7f, sizeof(int) * (sizee));
    118     memset(visited, false, sizeof(boolean) * (sizee));
    119     que.push(s);
    120     last[s] = 0;
    121     dis[s] = 0;
    122     laste[s] = 0;
    123     mflow[s] = INF;
    124     visited[s] = true;
    125     while(!que.empty()){
    126         int e = que.front();
    127         que.pop();
    128         visited[e] = false;
    129         for(int i = m_begin(g, e); i != 0; i = g[i].next){
    130             int &eu = g[i].end;
    131             if(dis[e] + g[i].cost < dis[eu] && g[i].flow < g[i].cap){
    132                 dis[eu] = dis[e] + g[i].cost;
    133                 last[eu] = e;
    134                 laste[eu] = i;
    135                 mflow[eu] = min(g[i].cap - g[i].flow, mflow[e]);
    136                 if(!visited[eu] && eu != t){
    137                     que.push(eu);
    138                     visited[eu] = true;
    139                 }
    140             }
    141         }
    142     }
    143     for(int i = t; i != s; i = last[i]){
    144         g[laste[i]].flow += mflow[t];
    145         g[g.reverse(laste[i])].flow -= mflow[t];
    146         cost += mflow[t] * g[laste[i]].cost;
    147     }
    148 }
    149 
    150 inline void minCostFlow(){
    151     s = 1 + n, t = n, sizee = 2 * n + 1;
    152     dis = new int[(const int)(sizee)];
    153     visited = new boolean[(const int)(sizee)];
    154     last = new int[(const int)(sizee)];
    155     laste = new int[(const int)(sizee)];
    156     mflow = new int[(const int)(sizee)];
    157     spfa();
    158     spfa();
    159 }
    160 
    161 inline void solve(){
    162     cost = 0;
    163     minCostFlow();
    164     printf("%d
    ", cost);
    165     g.clean();
    166 }
    167 
    168 int main(){
    169     while(init()){
    170         solve();        
    171     }
    172     return 0;
    173 }
  • 相关阅读:
    用C语言编写生成小学四则运算程序
    每周学习报告
    读现代软件工程有感和自我介绍
    第七天
    第五天
    第六天
    作业九:课程总结
    作业四:结对编程项目--四则运算
    psp记录个人项目花费时间
    作业三:代码规范,代码复查
  • 原文地址:https://www.cnblogs.com/yyf0309/p/6279192.html
Copyright © 2020-2023  润新知