首页 > 代码库 > [题解]uva 1658 Admiral

[题解]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\n", cost);165     g.clean();166 }167 168 int main(){169     while(init()){170         solve();        171     }172     return 0;173 }

 

[题解]uva 1658 Admiral