PAT (MOOC) 06-5. 关键活动 (30)

来源:互联网 发布:大数据社保行业应用 编辑:程序博客网 时间:2024/06/07 07:09
#include<vector>#include<cstring>#include<fstream>#include<algorithm>#include<map>#include<iostream>using namespace std;//ifstream fin("06-4.txt");//#define cin fin#define MAX 101typedef struct eg *ed;typedef struct ee *e;struct ee{int s, d;ee(int s, int d){this->s = s;this->d = d;}};struct eg{int weight;}edge[MAX][MAX];int n, m;int start, end1;bool vst[MAX];//此题是因为要判定环路 才设定vst数组的 否则是不用的vector<e> path_e, max_path_e;map<int, int> prio;int path = 0, max_path = -1;bool isru_zero(int v){for (int i = 1; i <= n; i++)if (edge[i][v].weight >= 0)return false;return true;}bool dfs(int v){if (path > max_path){end1 = v;max_path = path;}for (int i = 1; i <= n; i++){if (edge[v][i].weight > 0){if (vst[i]){return false;}path += edge[v][i].weight;vst[i] = true;if (!dfs(i))return false;path -= edge[v][i].weight;vst[i] = false;}}return true;}bool find(e p, vector<e> path, int size){for (int i = 0; i<size;i++)if (path[i]->s == p->s&&path[i]->d == p->d)return true;return false;}void dfs_re1(int v){if (isru_zero(v)){if (path >= max_path){//end1 = v;max_path = path;int size = path_e.size();max_path_e.resize(size);for (int i = 0; i < size; i++)max_path_e[i] = path_e[i];}}for (int i = 1; i <= n; i++){if (edge[i][v].weight > 0){path += edge[i][v].weight;e eg = new ee(i, v);path_e.push_back(eg);dfs_re1(i);path_e.pop_back();path -= edge[i][v].weight;}}}void dfs_re2(int v){if (isru_zero(v) && path == max_path){int max_size = max_path_e.size(), size = path_e.size();for (int i = 0; i<size; i++)if (!find(path_e[i], max_path_e, max_size)){max_path_e.push_back(path_e[i]);//max_size++;//没必要此时知道max_path_e的大小,查找时也不用找最后新加进的这些,最后输出再算总的即可}}for (int i = 1; i <= n; i++){if (edge[i][v].weight > 0){path += edge[i][v].weight;e eg = new ee(i, v);path_e.push_back(eg);dfs_re2(i);path_e.pop_back();path -= edge[i][v].weight;}}}bool cmp(const e &a,const e &b){if (a->s != b->s)return (a->s < b->s);else{int s1 = a->s, d1 = a->d, s2 = b->s, d2 = b->d;return (prio[s1*MAX + d1] > prio[s2*MAX + d2]);}}int main(){cin >> n >> m;memset(edge, -1, sizeof(edge));int c1, c2, w;for (int i = 1; i <= m; i++){cin >> c1 >> c2 >> w;edge[c1][c2].weight = w;prio[c1*MAX + c2] = i;}for (start = 1; start <= n; start++){if (isru_zero(start))break;}if (start == n + 1){printf("0\n"); return 0;}/*从这个入度为0的点开始沿正向深度遍历,找到那最远的点*/vst[start] = true;if (!dfs(start)){printf("0\n"); return 0;}vst[start] = false;start = end1;/* 再从最远点逆序遍历 找最远点- - 只要求得max_path值即可 */dfs_re1(start);printf("%d\n", max_path);path_e.clear();dfs_re2(start);sort(max_path_e.begin(), max_path_e.end(), cmp);int size = max_path_e.size();for (int i = 0; i < size; i++){printf("%d->%d\n", max_path_e[i]->s, max_path_e[i]->d);}}

0 0
原创粉丝点击