CodeForces 24A Ring road

来源:互联网 发布:微信公众号做淘宝客 编辑:程序博客网 时间:2024/05/29 11:45

A. Ring road
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Nowadays the one-way traffic is introduced all over the world in order to improve driving safety and reduce traffic jams. The government of Berland decided to keep up with new trends. Formerly all n cities of Berland were connected by n two-way roads in the ring, i. e. each city was connected directly to exactly two other cities, and from each city it was possible to get to any other city. Government of Berland introduced one-way traffic on all n roads, but it soon became clear that it's impossible to get from some of the cities to some others. Now for each road is known in which direction the traffic is directed at it, and the cost of redirecting the traffic. What is the smallest amount of money the government should spend on the redirecting of roads so that from every city you can get to any other?

Input

The first line contains integer n (3 ≤ n ≤ 100) — amount of cities (and roads) in Berland. Next n lines contain description of roads. Each road is described by three integers aibici (1 ≤ ai, bi ≤ n, ai ≠ bi, 1 ≤ ci ≤ 100) — road is directed from city ai to city bi, redirecting the traffic costs ci.

Output

Output single integer — the smallest amount of money the government should spend on the redirecting of roads so that from every city you can get to any other.

Sample test(s)
input
31 3 11 2 13 2 1
output
1
input
31 3 11 2 53 2 1
output
2
input
61 5 45 3 82 4 151 6 162 3 234 6 42
output
39
input
41 2 92 3 83 4 74 1 5
output
0

大致题意是有n个城市,原本是两两用双行道连接,后来改成单行道后导致有些城市不连通

即存在城市i和城市j,城市i的人没办法通过这些单行道到达城市j

于是政府打算将某些单行道的方向更改,最终使各城市互相都能到达

题目给出更改每个单行道的耗费,求总的最低耗费


题目看起来很复杂但是有一点很重要:刚开始每个城市都只与两个城市相连

因此这些城市实际上是形成一个环

以样例三为例:



假设顺时针方向为正方向,将所有不是顺时针方向的单行线都进行更改

图中紫色箭头表示方向正确,红色箭头表示方向错误

因此需要数组prev[i], later[i]分别记录指向城市i的城市和城市i指向的城市

而对于一个城市i,指向或被指向的城市最多有2个

因此数组分别开成prev[n+1][2], later[n+1][2]

prev[i][0], prev[i][1]表示指向城市i的不同城市;later[i][0], later[i][1]表示被城市i指向的不同城市(如果不存在,则值为0)


我们从数据给的第一个城市1开始,用i = later[i]来向前行走

当遇到方向错误的时候,可以发现这个城市被两个城市指向

因此可以用prev[i][1]是否为0来判断

例如5的下一个城市用next来表示 next = later[5][0] = 3

而prev[3][1]不等于0,因此指向城市3的一条单行线方向错误

用n_next来表示下下个城市 n_next = later[next][0] = 2

那么将更改2->3的费用计入result后将其改为正确的顺序,即3->2

同时不要忘了更改城市2和3的prev, later数组中的值,并将不存在的prev[i][1]或later[i][1]的重置为零


以此不断向前走,直到走回城市1即可


更改后的图:


此时输出min(result, sum-result)即可(sum为所有有向边的权值和)


代码如下:


#include<iostream>#include<string>#include<cstring>#include<cmath>#include<algorithm>#include<cstdio>using namespace std;const int maxn = 100+5;int dir[maxn][2][2], G[maxn], cost[maxn][maxn];int main() {  int n, head = 1, sum = 0, result = 0;  cin >> n;  memset(dir, 0, sizeof(dir));  memset(G, 0, sizeof(G));  memset(cost, 0, sizeof(cost));  for (int i = 0; i < n; i++) {    int pos, tar, t;    cin >> pos >> tar >> t;        if (dir[pos][1][0] == 0) dir[pos][1][0] = tar;    else dir[pos][1][1] = tar;        if (dir[tar][0][0] == 0) dir[tar][0][0] = pos;    else dir[tar][0][1] = pos;        cost[pos][tar] = t; sum += t;    if (i == 0) head = pos;  }    for (int i = head; dir[i][1][0] != head; i = dir[i][1][0]) {    int next = dir[i][1][0];    if (dir[next][0][1] != 0) {      int n_next;      if (dir[next][0][0] == i) {        n_next = dir[next][0][1];        dir[next][0][1] = 0;      }      else {        n_next = dir[next][0][0];        dir[next][0][0] = dir[next][0][1];        dir[next][0][1] = 0;      }      result += cost[n_next][next];      //cout << result << endl;      //cout << next << " " << n_next << endl;      dir[next][1][0] = n_next; dir[next][1][1] = 0;            if (dir[n_next][0][0] == 0) dir[n_next][0][0] = next;      else dir[n_next][0][1] = next;            if (dir[n_next][1][0] == next) { dir[n_next][1][0] = dir[n_next][1][1]; dir[n_next][1][1] = 0; }      else dir[n_next][1][1] = 0;    }  }    cout << min(result, sum-result) << endl;    return 0;}


后来看了下同学的代码,用递归可以减少代码量,就酱~(≧▽≦)/~

0 0