#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 101
typedef 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);
}
}
PAT (MOOC) 06-5. 关键活动 (30)
最新推荐文章于 2015-10-15 23:36:27 发布