2015 ACM Arabella Collegiate Programming Contest

  题目链接:https://vjudge.net/contest/154238#overview

  ABCDE都是水题。

  F题,一开始分类讨论,结果似乎写挫了,WA了一发。果断换并查集上,A了。

  G题,状态压缩DP,不难写,但是时限有点紧,读入也比较恶心。。值得注意的是计算一个数二进制下有几个1可以用__builtin_popcount(mask);判断a和b在二进制表示下a是不是b的子集可以用(a&b)==a;另外字符串s想移除最后一位可以s.resize(s.size()-1)或者s.erase(s.end()-1)。

  H题,tarjan题,思路不难。无向图缩点以后找一下树的直径,再遍历一下即可。但是被两个傻逼错误卡了好久。。好弱啊。。顺便注意下,无向图的缩点需要在tarjan的时候加一个参数fa,或者用head数组实现邻接表。后者因为反向边和原边的编号是相邻的,可以直接用vis数组来使得反向边不访问,这个方法的好处是可以处理重边,而第一个方法不行。具体的代码实现我之前的模板里有。。贴一下这题的代码好了:

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <string.h>
  4 #include <vector>
  5 #include <map>
  6 #include <set>
  7 #include <queue>
  8 #include <iostream>
  9 #include <stdlib.h>
 10 #include <string>
 11 #include <stack>
 12 using namespace std;
 13 const int inf = 0x3f3f3f3f;
 14 typedef long long ll;
 15 typedef pair<int,int> pii;
 16 const int N = 100000 + 5;
 17 
 18 int n,m,dfs_clock,dfn[N],low[N];
 19 int belong[N],scc_cnt,id[N];
 20 stack<int> S;
 21 struct edge
 22 {
 23     int v,w,nxt;
 24 }G[N*8];
 25 int head[N],head2[N],etot;
 26 vector<int> bcc[N];
 27 void addEdge(int u,int v,int w,int* head)
 28 {
 29     G[etot] = (edge){v,w,head[u]};
 30     head[u] = etot++;
 31 }
 32 
 33 int pos = 0;
 34 void init()
 35 {
 36     etot = 0;
 37     memset(head,-1,sizeof head);
 38     memset(head2,-1,sizeof head2);
 39     dfs_clock = 0;
 40     memset(dfn,0,sizeof(dfn));
 41     memset(belong,0,sizeof(belong));
 42     scc_cnt = 0;
 43     memset(id,-1,sizeof(id));
 44 }
 45 
 46 void tarjan(int u,int fa)
 47 {
 48     dfn[u]=low[u]=++dfs_clock;
 49     S.push(u);
 50     for(int i=head[u];i!=-1;i=G[i].nxt)
 51     {
 52         edge e = G[i];
 53         int v = e.v;
 54         if(!dfn[v])
 55         {
 56             tarjan(v,u);
 57             low[u]=min(low[u],low[v]);
 58         }
 59         else if(dfn[v] < dfn[u] && v != fa)
 60         {
 61             low[u]=min(low[u],dfn[v]);
 62         }
 63     }
 64     if(low[u]==dfn[u])
 65     {
 66         scc_cnt++;
 67         bcc[scc_cnt].clear();
 68         for(;;)
 69         {
 70             int x = S.top();S.pop();
 71             belong[x] = scc_cnt;
 72             bcc[scc_cnt].push_back(x);
 73             if(id[scc_cnt] == -1 || id[scc_cnt] > x) id[scc_cnt] = x;
 74             if(x==u) break;
 75         }
 76     }
 77 
 78 }
 79 
 80 ll d[N],d1[N],d2[N];
 81 void dfs(int u,int fa,ll* dis)
 82 {
 83     for(int i=head2[u];i!=-1;i=G[i].nxt)
 84     {
 85         edge e = G[i];
 86         int v = e.v, w = e.w;
 87         if(v == fa) continue;
 88         dis[v] = dis[u] + w;
 89         dfs(v,u,dis);
 90     }
 91 }
 92 
 93 void solve()
 94 {
 95     for(int i=1;i<=n;i++)
 96     {
 97         if(!dfn[i]) tarjan(i,-1);
 98     }
 99 
100     for(int i=1;i<=n;i++)
101     {
102         int u = belong[i];
103         for(int j=head[i];j!=-1;j=G[j].nxt)
104         {
105             edge e = G[j];
106             int v = belong[e.v], w = e.w;
107             if(u != v)
108             {
109                 addEdge(u,v,w,head2);
110             }
111         }
112     }
113 
114     int x = belong[1];
115     d[x] = 0;
116     dfs(x,-1,d);
117     int y = x;
118     for(int i=1;i<=scc_cnt;i++)
119     {
120         if(d[i] > d[y])
121         {
122             y = i;
123         }
124     }
125     d1[y] = 0;
126     dfs(y,-1,d1);
127     x = y;
128     for(int i=1;i<=scc_cnt;i++)
129     {
130         if(d1[i] > d1[x])
131         {
132             x = i;
133         }
134     }
135     d2[x] = 0;
136     dfs(x,-1,d2);
137     int ans_id = min(id[x],id[y]);
138     ll len = d1[belong[ans_id]] + d2[belong[ans_id]];
139     for(int i=1;i<=scc_cnt;i++)
140     {
141         ll temp = max(d1[i], d2[i]);
142         if(temp < len)
143         {
144             ans_id = id[i];
145             len = temp;
146         }
147         else if(temp == len && id[i] < ans_id) ans_id = id[i];
148     }
149     printf("%d %I64d
",ans_id,len);
150 }
151 
152 int main()
153 {
154     int T;
155     scanf("%d",&T);
156     for(int kase=1;kase<=T;kase++)
157     {
158         init();
159         scanf("%d%d",&n,&m);
160         for(int i=1;i<=m;i++)
161         {
162             int u,v,w;
163             scanf("%d%d%d",&u,&v,&w);
164             addEdge(u,v,w,head);
165             addEdge(v,u,w,head);
166         }
167         solve();
168     }
169 }
H题
原文地址:https://www.cnblogs.com/zzyDS/p/6567713.html