lightoj1210Efficient Traffic System
2015-11-16 20:52
295 查看
思路:给定一个有向图,问至少需要添加几条有向边可以使得图成为一个强连通图。
显然是需要缩点的,因为一个环上的点是可以互达的,可以看成一个点,如果图本
身就是强连通的输出0,因为不需要添加。否则就看缩点后每个点的入度与出度。
没有出的,要添加,没有入的要添加,,,这里就去其最大值(因为没有入的可以
和没有出的点之间加边,剩下的就要和其他任何点之间建边了)。
显然是需要缩点的,因为一个环上的点是可以互达的,可以看成一个点,如果图本
身就是强连通的输出0,因为不需要添加。否则就看缩点后每个点的入度与出度。
没有出的,要添加,没有入的要添加,,,这里就去其最大值(因为没有入的可以
和没有出的点之间加边,剩下的就要和其他任何点之间建边了)。
// #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> // #define DEBUG #ifdef DEBUG #define debug(...) printf( __VA_ARGS__ ) #else #define debug(...) #endif #define MEM(x,y) memset(x, y,sizeof x) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 20010; int head[maxn], to[maxn << 2], nxt[maxn << 2]; int dfn[maxn], low[maxn], belong[maxn]; bool vis[maxn]; int Time; int scc; int n ,m; stack<int> st; int tol; void add(int u,int v){ to[tol] = v; nxt[tol] = head[u]; head[u] = tol++; } void Tarjan(int u){ dfn[u] = low[u] = Time++; vis[u] = true; st.push(u); for (int i = head[u];i != -1;i = nxt[i]){ int v = to[i]; if (dfn[v] == -1){ Tarjan(v); low[u] = min(low[u], low[v]); }else if (vis[v] && dfn[v] < low[u]){ low[u] = dfn[v]; } } if (dfn[u] == low[u]){ scc++; while(true){ int v = st.top(); st.pop(); vis[v] = false; belong[v] = scc; if (v == u) break; } } } int in[maxn], out[maxn]; void dfs(int u){ dfn[u] = 1; for (int i = head[u];i != -1;i = nxt[i]){ int v = to[i]; int a = belong[u]; int b = belong[v]; if (a != b){ in[b]++; out[a]++; } if (dfn[v] == -1) dfs(v); } } int solve(){ if (scc == 1) return 0; int a = 0,b = 0; for (int i = 1;i <= scc;++i){ if (!in[i]) a++; if (!out[i]) b++; } return max(a,b); } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int icase = 0, t; cin >> t; while(t--){ scanf("%d%d",&n,&m); tol = scc = 0; Time = 0; MEM(belong, -1); MEM(head, -1); MEM(vis, false); MEM(dfn, -1); for (int i = 0, a, b;i < m;++i){ scanf("%d%d",&a, &b); add(a,b); } for (int i = 1;i <= n;++i) if (dfn[i] == -1) Tarjan(i); // cout << "scc = " << scc << endl; MEM(dfn, -1); MEM(in, 0); MEM(out, 0); for (int i = 1;i <= n;++i) if (dfn[i] == -1) dfs(i); printf("Case %d: %d\n", ++icase, solve()); } return 0; }
相关文章推荐
- iOS图文混排
- LayoutInflater
- 【python】xml Elementtree 学习一
- 将maven项目自动部署至私有nexus maven仓库
- 设计一款给爸爸妈妈的手机
- 顶点法线和面法线
- Objective-c:内存管理
- Objective-C运行时定义的几种重要的类型
- ViewPager
- 《leetCode》:N-Queens(奇葩的测试平台,居然不能AC)
- (原创)一般矩阵 Matrix类
- HDU 5524:Subtrees
- 列出各个部门中薪水最高的员工
- hdu 1023+1030+1134 卡特兰数+大数模板处理
- android菜鸟修炼记
- HDU 5524:Subtrees
- OpenCV在win32下不显示图像
- mysql初步备份方案
- hihocoder 1257 Snake Carpet 模拟构造题||2015北京现场赛I题
- 如何通过Fiddler对安卓应用进行抓包