loj 1429(可相交的最小路径覆盖)
来源:互联网 发布:dj香烟淘宝链接 编辑:程序博客网 时间:2024/06/03 15:31
题目链接:http://lightoj.com/volume_showproblem.php?problem=1429
思路:这道题还是比较麻烦的,对于求有向图的可相交的最小路径覆盖,首先要解决成环问题,可以先染色缩点重建图,然后就是如何来处理这个路径可以相交这个问题,这里可以用bfs求出任意两点之间是否可达,如果可达,就连边,然后就是HK算法求最大匹配了,最小路径覆盖 = 顶点数 - 最大匹配。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <stack> 8 using namespace std; 9 10 const int MAXN = (1000 + 10); 11 const int MAXM = (10000 + 10); 12 int n, m; 13 int cnt, scc_count; 14 bool Instack[MAXN]; 15 int low[MAXN], dfn[MAXN], color[MAXN]; 16 vector<int > g[MAXN]; 17 stack<int > S; 18 19 void Tarjan(int u) 20 { 21 low[u] = dfn[u] = ++cnt; 22 Instack[u] = true; 23 S.push(u); 24 for (int i = 0; i < (int)g[u].size(); i++) { 25 int v = g[u][i]; 26 if (dfn[v] == 0) { 27 Tarjan(v); 28 low[u] = min(low[u], low[v]); 29 } else if (Instack[v]) { 30 low[u] = min(low[u], dfn[v]); 31 } 32 } 33 if (low[u] == dfn[u]) { 34 scc_count++; 35 int v; 36 do { 37 v = S.top(); 38 S.pop(); 39 Instack[v] = false; 40 color[v] = scc_count; 41 } while (u != v); 42 } 43 } 44 45 bool Isok[MAXN][MAXN]; 46 bool mark[MAXN]; 47 vector<int > reg[MAXN]; 48 49 void bfs(int st) 50 { 51 memset(mark, false, sizeof(mark)); 52 queue<int >que; 53 que.push(st); 54 mark[st] = true; 55 while (!que.empty()) { 56 int u = que.front(); 57 que.pop(); 58 for (int i = 0; i < (int)reg[u].size(); i++) { 59 int v = reg[u][i]; 60 if (!mark[v]) { 61 mark[v] = true; 62 que.push(v); 63 } 64 } 65 } 66 } 67 68 void Build() 69 { 70 for (int i = 1; i <= scc_count; i++) { 71 reg[i].clear(); 72 } 73 for (int i = 1; i <= scc_count; i++) { 74 for (int j = 1; j <= scc_count; j++) { 75 if (i != j && Isok[i][j]) { 76 reg[i].push_back(j); 77 } 78 } 79 } 80 } 81 82 int lx[MAXN], ly[MAXN]; 83 int distx[MAXN], disty[MAXN]; 84 85 bool MaxMatch_bfs() 86 { 87 bool flag = false; 88 memset(distx, 0, sizeof(distx)); 89 memset(disty, 0, sizeof(disty)); 90 queue<int > que; 91 for (int i = 1; i <= scc_count; i++) { 92 if (lx[i] == -1) que.push(i); 93 } 94 while (!que.empty()) { 95 int u = que.front(); 96 que.pop(); 97 for (int i = 0; i < (int)reg[u].size(); i++) { 98 int v = reg[u][i]; 99 if (disty[v] == 0) {100 disty[v] = distx[u] + 1;101 if (ly[v] == -1) flag = true;102 else {103 distx[ly[v]] = disty[v] + 1;104 que.push(ly[v]);105 }106 }107 }108 }109 return flag;110 }111 112 int dfs(int u)113 {114 for (int i = 0; i < (int)reg[u].size(); i++) {115 int v = reg[u][i];116 if (disty[v] == distx[u] + 1) {117 disty[v] = 0;118 if (ly[v] == -1 || dfs(ly[v])) {119 ly[v] = u;120 lx[u] = v;121 return 1;122 }123 }124 }125 return 0;126 }127 128 int MaxMatch()129 {130 memset(lx, -1, sizeof(lx));131 memset(ly, -1, sizeof(ly));132 int res = 0;133 while (MaxMatch_bfs()) {134 for (int i = 1; i <= scc_count; i++) {135 if (lx[i] == -1) res += dfs(i);136 }137 }138 return res;139 }140 141 142 int main()143 {144 int _case, t = 1;145 scanf("%d", &_case);146 while (_case--) {147 scanf("%d %d", &n, &m);148 for (int i = 1; i <= n; i++) {149 g[i].clear();150 reg[i].clear();151 }152 while (m--) {153 int u, v;154 scanf("%d %d", &u, &v);155 g[u].push_back(v);156 }157 //强联通缩点重建图158 cnt = scc_count = 0;159 memset(dfn, 0, sizeof(dfn));160 for (int i = 1; i <= n; i++) {161 if (dfn[i] == 0) Tarjan(i);162 }163 for (int u = 1; u <= n; u++) {164 for (int i = 0; i < (int)g[u].size(); i++) {165 int v = g[u][i];166 if (color[u] != color[v]) {167 reg[color[u]].push_back(color[v]);168 }169 }170 }171 //bfs求出新图中的任意两点之间是否可达172 memset(Isok, false, sizeof(Isok));173 for (int i = 1; i <= scc_count; i++) {174 bfs(i);175 for (int j = 1; j <= scc_count; j++) {176 if (mark[j]) {177 Isok[i][j] = true;178 }179 }180 }181 //对于那些可达的点重新连边182 Build();183 //bfs求解最大匹配;184 //最小路径覆盖 = 顶点数 - 最大匹配数185 int ans = MaxMatch();186 printf("Case %d: %d\n", t++, scc_count- ans);187 }188 return 0;189 }
0 0
- loj 1429(可相交的最小路径覆盖)
- poj 2594(可相交的最小路径覆盖)
- POJ 2594 可相交的最小路径覆盖
- poj2594(可相交最小路径覆盖)
- POJ Treasure Exploration(DAG最小可相交路径覆盖)
- Poj 2594 Treasure Exploration【可相交最小路径覆盖】
- poj2594 Treasure Exploration(可相交最小路径覆盖)
- POJ 2594 浅谈可相交的二分图DAG最小路径覆盖
- POJ 2594 允许有相交点的最小路径覆盖
- CIA3 NOI接站(tarjan缩环+Floyd传递闭包+可相交最小路径覆盖)
- loj 6197. 法克 最小路径覆盖 好题
- bzoj 2150 最小不相交路径覆盖
- poj2594点可重复的最小路径覆盖
- 可重叠的最小路径覆盖 poj2594 Treasure Exploration
- POJ-2594-Treasure Exploration-(路径相交的最小路径覆盖+闭包传递)
- POJ 2594 (最小路径覆盖+可重点)
- UVALive 3126 出租车(DAG的最小不相交路径覆盖)
- hdu 4606(线段相交 + 最短路 + 最小路径覆盖)
- loj 1257 (求树上每一个点到树上另一个点的最长距离)
- loj 1337
- loj 1357(树形dp)
- loj 1210 (求最少的加边数使得图变成强连通)
- loj 1406(状态压缩)
- loj 1429(可相交的最小路径覆盖)
- poj上的dp专题
- poj 3895(求无向图的最大简单环)
- spfa求最长路
- FANN的图形用户界面形式
- hdu 3001(状压dp, 3进制)
- zoj 3471(状态压缩)
- 汇编考试小结
- 单调队列,斜率优化dp 专题