CodeForces 24A Ring road (简单题)

题目类型  简单题

题目意思
有一个连通图 包含 n 个点 n 条无向边 其中每个点都与其他的两个点直接相连 (即这是一个环)
现在这个环的边变成了有向边 变成了有向边后得到的有向图不一定是强连通的 
(强连通图是指一个有向图中任意两点v1、v2间存在v1到v2的路径及v2到v1的路径的图)

所以现在给出 n 条有向边和把某条有向边转换方向后的代价, 问要使输入的有向图变成一个强连通图
例如输入
3
1 3 1
1 2 1
3 2 1
表示有一条有向边 1 -> 3 如果把这条边变成 3 -> 1 的代价是 1
表示有一条有向边 1 -> 2 如果把这条边变成 2 -> 1 的代价是 1
表示有一条有向边 3 -> 2 如果把这条边变成 2 -> 3 的代价是 1
对于输入的这个有向图是不存在 2 -> 3 的路径的 所以可以把 有向边 1 -> 2 变为 2 -> 1 这样图中任意两点均相互可达

解题方法
可以发现 对于输入的有向图(不考虑边的方向的话原来是一个环) 要使它变成强连通的 那么它的边的方向一定是一致的
即如果不全是顺时针的就一定全是逆时针的, 所以对于两种情况计算一下代价就行了

参考代码  - 有疑问的地方在下方留言 看到会尽快回复的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <vector>

using namespace std;

typedef long long LL;

const int MAXN = 1e2 + 10;

vector<int>edge[MAXN];
vector<int>w[MAXN];

int main() {
  int n;
  while(scanf("%d", &n) != EOF) {
    for( int i=1; i<=n; i++ ) edge[i].clear(), w[i].clear();
    int a, b, c;
    for( int i=0; i<n; i++ ) {
      scanf("%d%d%d", &a, &b, &c);
      edge[a].push_back(b);
      w[a].push_back(c);
      edge[b].push_back(a);
      w[b].push_back(-c);
    }
    int res = 0;
    int pre = 1;
    int next = edge[1][0];
    if(w[1][0] < 0) res += -w[1][0];
    while(next != 1) {
      //printf("next = %d\n", next);
      int tmp = edge[next][0];
      if(tmp == pre) {
        tmp = edge[next][1];
        if(w[next][1] < 0) res += -w[next][1];
        pre = next;
        next = tmp;
      }
      else {
        if(w[next][0] < 0) res += -w[next][0];
        pre = next;
        next = tmp;
      }
    }
    int t_res = 0;
    pre = 1;
    next = edge[1][1];
    if(w[1][1] < 0) t_res += -w[1][1];
    while(next != 1) {
      int tmp = edge[next][0];
      if(tmp == pre) {
        tmp = edge[next][1];
        if(w[next][1] < 0) t_res += -w[next][1];
        pre = next;
        next = tmp;
      }
      else {
        if(w[next][0] < 0) t_res += -w[next][0];
        pre = next;
        next = tmp;
      }
    }
    res = min(res, t_res);
    printf("%d\n", res);
  }
  return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值