1.所有点对间的最短路径
a.定义:指以图G=(V,E)为对象,求G中每两点之间最短距离的问题
b.核心:关键在于判断在经过中间点与不经过中间点之间的两者距离的最小值,可用弗洛伊德算法求解
c.代码:
2.拓朴排序:
a.题目:求输出对给定DAG G进行拓朴排序后的顶点顺序
b.核心算法:用深度优先搜索或者广度优先搜索就能实现拓朴排序
c.代码:
a.题目:求权值非负的无向树T的直径,即求此树最远结点间的距离。
b.核心:任意在图中选一节点,求此节点到此图两边界间的距离。
c.代码:
a.定义:指以图G=(V,E)为对象,求G中每两点之间最短距离的问题
b.核心:关键在于判断在经过中间点与不经过中间点之间的两者距离的最小值,可用弗洛伊德算法求解
c.代码:
//
// Created by 叶子 on 2018/2/6.
// 使用弗洛伊德算法计算所有点对间的最短路径
//
#include "iostream"
#include "algorithm"
#include "vector"
#include "climits"
using namespace std;
static const int MAX = 100;
static const long long INFTY = ( 1LL < 32);
int n;
long long d[MAX][MAX];
void floyd(){
for (int k = 0 ; k < n ; k ++){
for ( int i = 0 ; i < n ; i ++){
if ( d[i][k] == INFTY) continue;
for ( int j = 0 ; j < n ; j ++){
if ( d[k][j] == INFTY ) continue;
d[i][j] = min(d[i][j],d[i][k] + d[k][j]);
}
}
}
}
int main(){
int e,u,v,c;
cin >> n >> e;
for ( int i = 0 ; i < n ; i ++){
for ( int j = 0 ; j < n ; j ++){
d[i][j] = (( i == j ) ? 0 : INFTY);
}
}
for ( int i = 0 ; i < e ; i ++){
cin >> u >> v >> c;
d[u][v] = c;
}
floyd();
bool negative = false;
for ( int i = 0 ; i < n ; i ++) if ( d[i][i] < 0 ) negative = true;
if ( negative ){
cout << "NEGATIVE CYCLE" << endl;
}else{
for ( int i = 0 ; i < n ; i ++){
for ( int j = 0 ; j < n ; j ++){
if ( j ) cout << " ";
if ( d[i][j] == INFTY ) cout << "INF";
else cout << d[i][j];
}
cout <<endl;
}
}
return 0;
}
2.拓朴排序:
a.题目:求输出对给定DAG G进行拓朴排序后的顶点顺序
b.核心算法:用深度优先搜索或者广度优先搜索就能实现拓朴排序
c.代码:
//
// Created by 叶子 on 2018/2/6.
// 广度优先搜索的拓朴排序
//
#include "iostream"
#include "vector"
#include "queue"
#include "list"
using namespace std;
static const int MAX = 100000;
vector<int> G[MAX];
list<int> out;
bool V[MAX];
int N;
int indeg[MAX];
void bfs(int s){
queue<int> q;
q.push(s);
V[s] = true;
while ( !q.empty()){
int u = q.front();
q.pop();
out.push_back(u);
for ( int i = 0 ; i < G[u].size() ; i ++){
int v = G[u][i];
indeg[v]--;
if ( indeg[v] == 0 && !V[v]){
V[v] = true;
q.push(v);
}
}
}
}
void tsort(){
for ( int i = 0; i < N ; i ++){
indeg[i] = 0;
}
for ( int u = 0 ; u < N ; u ++){
for ( int i = 0 ; i < G[u].size() ; i ++){
int v = G[u][i];
indeg[v]++;
}
}
for ( int u = 0 ; u < N ; u ++){
if ( indeg[u] == 0 && !V[u] ) bfs(u);
}
for ( list<int>::iterator it = out.begin(); it != out.end() ; it ++){
cout << *it << endl;
}
}
int main(){
int s,t,M;
cin >> N >> M;
for ( int i = 0 ; i < N ; i ++) V[i] = false;
for ( int i = 0 ; i < M ; i ++){
cin >> s >> t;
G[s].push_back(t);
}
tsort();
return 0;
}
3.树的直径:
a.题目:求权值非负的无向树T的直径,即求此树最远结点间的距离。
b.核心:任意在图中选一节点,求此节点到此图两边界间的距离。
c.代码:
//
// Created by 叶子 on 2018/2/6.
// 用深度优先搜索求树的直径
//
#include "iostream"
#include "queue"
using namespace std;
const int MAX = 100000;
const int INFTY = ( 1 << 30);
class Edge{
public:
int t,w;
Edge(){}
Edge(int t,int w) : t(t),w(w) {}
};
vector<Edge> G[MAX];
int n,d[MAX];
void bfs(int s){
for (int i = 0 ; i < n ; i ++) d[i] = INFTY;
queue<int> Q;
Q.push(s);
d[s] = 0;
int u;
while ( !Q.empty()){
u = Q.front();
Q.pop();
for ( int i = 0 ; i < G[u].size(); i ++){
Edge e = G[u][i];
if ( d[e.t] == INFTY ){
d[e.t] = d[u] + e.w;
Q.push(e.t);
}
}
}
}
void solve(){
bfs(0);
int maxv = 0;
int tgt = 0;
for ( int i = 0 ; i < n ; i ++){
if ( d[i] == INFTY ) continue;
if ( maxv < d[i] ){
maxv = d[i];
tgt = i;
}
}
bfs(tgt);
maxv = 0;
for ( int i = 0 ; i < n ; i ++){
if ( d[i] == INFTY ) continue;
maxv = max(maxv,d[i]);
}
cout << maxv << endl;
}
int main(){
int s,t,w;
cin >> n;
for ( int i = 0 ; i < n - 1 ; i ++){
cin >> s >> t >> w;
G[s].push_back(Edge(t,w));
G[t].push_back(Edge(s,w));
}
solve();
return 0;
}