zoukankan      html  css  js  c++  java
  • CodeForces 219D Choosing Capit

    题目链接:http://codeforces.com/contest/219/problem/D

    题目大意:

      给定一个n个节点的数和连接n个节点的n - 1条有向边,现在要选定一个节点作为起始节点,从这个点出发需要能走到其余每个节点,途中必然要调整有向边的方向,请求出当选定哪些节点作为初始节点时,所要调整的有向边最少,输出最小调整的边数和这些节点。

    分析:

      Hint:城市结构是树型结构。

    代码如下:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3  
      4 #define rep(i,n) for (int i = 0; i < (n); ++i)
      5 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
      6 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
      7 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
      8 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
      9  
     10 #define pr(x) cout << #x << " = " << x << "  "
     11 #define prln(x) cout << #x << " = " << x << endl
     12  
     13 #define LOWBIT(x) ((x)&(-x))
     14  
     15 #define ALL(x) x.begin(),x.end()
     16 #define INS(x) inserter(x,x.begin())
     17  
     18 #define ms0(a) memset(a,0,sizeof(a))
     19 #define msI(a) memset(a,inf,sizeof(a))
     20 #define msM(a) memset(a,-1,sizeof(a))
     21  
     22 #define pii pair<int,int> 
     23 #define piii pair<pair<int,int>,int> 
     24 #define mp make_pair
     25 #define pb push_back
     26 #define fi first
     27 #define se second
     28  
     29 inline int gc(){
     30     static const int BUF = 1e7;
     31     static char buf[BUF], *bg = buf + BUF, *ed = bg;
     32      
     33     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
     34     return *bg++;
     35 } 
     36  
     37 inline int ri(){
     38     int x = 0, f = 1, c = gc();
     39     for(; c<48||c>57; f = c=='-'?-1:f, c=gc());
     40     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
     41     return x*f;
     42 }
     43  
     44 typedef long long LL;
     45 typedef unsigned long long uLL;
     46 const int inf = 1e9 + 9;
     47 const LL mod = 1e9 + 7;
     48 const int maxN = 2e5 + 7;
     49  
     50 struct Node{
     51     vector< pii > next;
     52 };
     53  
     54 int n, ans;
     55 // dp[i]表示以i号城市为首都所要反转的道路数
     56 int dp[maxN];
     57 int vis[maxN];
     58 Node nodes[maxN];
     59 queue< int > Q;
     60  
     61 // 求dp[x]
     62 inline int dfs(int x) {
     63     if(nodes[x].next.empty()) return 0;
     64      
     65     int ret = 0;
     66     foreach(i, nodes[x].next) {
     67         int y = i->fi, z = i->se;
     68         if(vis[y]) continue;
     69         vis[x] = 1;
     70         if(z == -1) ++ret;
     71         ret += dfs(y);
     72     }
     73     return ret;
     74 }
     75  
     76 // 如果dp[i]已知,假设j号城市与i号城市相连,由于整个城市图是树形结构,
     77 // 因此dp[j]与dp[i]除了他们的连线有分歧,其余应该反转的道路数量都是一样的
     78 // 因此可由已算出来的1号城市为中心,向外做BFS
     79 inline void bfs() {
     80     ms0(vis);
     81     vis[1] = 1;
     82     Q.push(1);
     83     ans = dp[1];
     84  
     85     while(!Q.empty()) {
     86         int tmp = Q.front();
     87         Q.pop();
     88  
     89         foreach(i, nodes[tmp].next) {
     90             int y = i->fi, z = i->se;
     91             if(vis[y]) continue;
     92             vis[y] = 1;
     93             dp[y] = dp[tmp] + z;
     94             ans = min(ans, dp[y]);
     95             Q.push(y);
     96         }
     97     }
     98 }
     99  
    100 int main(){
    101     while(cin >> n) {
    102         ms0(vis);
    103         rep(i, n + 1) nodes[i].next.clear();
    104         rep(i, n-1) {
    105             int x, y;
    106             cin >> x >> y;
    107             nodes[x].next.push_back(mp(y, 1));
    108             nodes[y].next.push_back(mp(x, -1));
    109         }
    110         dp[1] = dfs(1);
    111          
    112         bfs();
    113          
    114         cout << ans << endl;
    115         For(i, 1, n) if(ans == dp[i]) cout << i << " ";
    116         cout << endl;
    117     }
    118     return 0;
    119 }
    View Code
  • 相关阅读:
    交叉编译OpenCV的教程——基于aarch64-linux-gnu的交叉编译器
    Day01:我的Python学习之路
    将中文库导入到ARM板子中以解决中文显示乱码的教程
    Linux环境下挂载SD卡的教程
    Ubuntu下压缩与解压各种文件的命令
    Ubuntu14.04环境下Qt5.5以上版本无法输入中文的解决教程
    编程之美:队列中的最大最小值
    leetcode:Compare Version Numbers
    leetcode:Search for a Range
    csapp:无符号数可能造成的程序bug
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/10752527.html
Copyright © 2011-2022 走看看