简单的图论题
方法一:Floyd求最小环
难点:建图
技巧:
①运算符重载operator
②map映射
代码:
#include <iostream> #include <algorithm> #include <cstring> #include <map> using namespace std; const int MAXN = 110; const int INF = 10000000; struct Node { int s[9]; Node() { memset(s, 0, sizeof(s)); } bool operator==(const Node& a) const { for(int i=0; i<9; i++) { if(s[i] != a.s[i]) return false; } return true; } bool operator<(const Node& a) const { for(int i=0; i<9; i++) { if(s[i] < a.s[i]) return true; else if(s[i] > a.s[i]) return false; } return false; } }; int n, s, ls, n1s, n2s, sta, des, cnt, G[MAXN][MAXN], dis[MAXN][MAXN]; map <Node, int> mp; int floyd() { int ans = INF; memcpy(dis, G, sizeof(G)); for(int k=1; k<=cnt; k++) { for(int i=1; i<k; i++) for(int j=i+1; j<k; j++) { ans = min(ans, dis[i][j] + G[i][k] + G[k][j]); } for(int i=1; i<=cnt; i++) { for(int j=1; j<=cnt; j++) { dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); } } } return ans; } int main() { for(int i=0; i<MAXN; i++) { fill(G[i], G[i]+MAXN, INF); } cin >> n; for(int i=1; i<=n; i++) { Node f1, f2; cin >> s >> ls >> n1s >> n2s; f1.s[8] = f2.s[8] = s; while(n1s--) cin >> f1.s[n1s]; sort(f1.s, f1.s + 9); if(mp[f1] == 0) mp[f1] = ++cnt; while(n2s--) cin >> f2.s[n2s]; sort(f2.s, f2.s+9); if(mp[f2] == 0) mp[f2] = ++cnt; sta = mp[f1]; des = mp[f2]; G[sta][des] = G[des][sta] = ls; } cout << floyd() << endl; return 0; }
方法二:dfs搜索
难点:无(除非你连dfs都不会……)
代码:
#include <iostream> using namespace std; const int MAXN = 110; const int INF = 1000000; int n, s, ans, start, ls[MAXN], num[MAXN][2], a[MAXN][2][10]; int checkdir(int s, int t) { for(int i=1; i<=num[t][0]; i++) { if(a[t][0][i] == s) return 0; } return 1; } void dfs(int u, int dir, int sum) { if(sum > ans) return ; if(u == start && sum > 0) { ans = min(ans, sum); return ; } for(int i=1; i<=num[u][dir]; i++) { int v = a[u][dir][i]; dfs(v, 1-checkdir(u, v), sum+ls[u]); } } int main() { cin >> n; ans = 10000000; for(int i=1; i<=n; i++) { cin >> s; cin >> ls[s] >>num[s][0] >> num[s][1]; for(int j=1; j<=num[s][0]; j++) cin >> a[s][0][j]; for(int j=1; j<=num[s][1]; j++) cin >> a[s][1][j]; } for(start=1; start<=n; start++) { dfs(start, 0, 0); } cout << ans; return 0; }
方法三:
删除环的一条边,求剩下的最短路再加上这条边的长度
代码:略(只是模板的一点改动,没有什么好提示的)
嗯?我做完了?三种方法?
蒟蒻的程序,有待提高!