本题说了是无环图,所以就是一片森林了。 而对于树上的任意两点,我们可以用LCA求其距离。距离为两个子节点到根的距离和减去最近祖先到根的距离的2倍。具体画图便可看出来。
并且图是无向图,所以LCA时需要进行标记
POJ 1986同这道题 基本一样
/*
ID: CUGB-wwj
PROG:
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define INF 1111111111
#define MAXN 10005
#define MAXM 1000005
#define L(x) x<<1
#define R(x) x<<1|1
#define eps 1e-4
using namespace std;
struct node
{
int v, w;
node(){}
node(int a, int b){ v = a; w = b;}
};
vector<node>tree[MAXN], ask[MAXN]; //tree里w代表权值,ask里w代表序号
int dis[MAXN], father[MAXN], vis[MAXN], ans[MAXM];
int n, m, c;
void init()
{
for(int i = 0; i <= n; i++)
{
dis[i] = 0;
father[i] = i;
vis[i] = 0;
tree[i].clear();
ask[i].clear();
}
}
int find(int x)
{
if(father[x] == x) return x;
int t = find(father[x]);
father[x] = t;
return t;
}
void LCA(int u, int w, int root)
{
dis[u] = w;
father[u] = u;
vis[u] = root;
int size = tree[u].size();
for(int i = 0; i < size; i++)
{
if(!vis[tree[u][i].v])
{
LCA(tree[u][i].v, tree[u][i].w + w, root);
father[tree[u][i].v] = u;
}
}
size = ask[u].size();
for(int i = 0; i < size; i++)
{
if(vis[ask[u][i].v])
{
if(vis[ask[u][i].v] == root)
ans[ask[u][i].w] = dis[u] + dis[ask[u][i].v] - 2 * dis[find(ask[u][i].v)];
else ans[ask[u][i].w] = -1;
}
}
}
int main()
{
int u, v, w;
while(scanf("%d%d%d", &n, &m, &c) != EOF)
{
init();
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d", &u, &v, &w);
node tmp1(v, w);
node tmp2(u, w);
tree[u].push_back(tmp1);
tree[v].push_back(tmp2);
}
for(int i = 1; i <= c; i++)
{
scanf("%d%d", &u, &v);
node tmp1(v, i);
node tmp2(u, i);
ask[u].push_back(tmp1);
ask[v].push_back(tmp2);
}
for(int i = 1; i <= n; i++)
{
if(!vis[i]) LCA(i, 0, i);
}
for(int i = 1; i <= c; i++)
{
if(ans[i] == -1) printf("Not connected\n");
else printf("%d\n", ans[i]);
}
}
return 0;
}
分享到:
相关推荐
poj 2763 程序 线段树 LCA 2000MS AC
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题...
poj1379 给予平面内一个点集; 使用模拟退火求出一个点使该点到上述点集内任意一点最短距离最长。
C语言 poj npu 西工大 C语言Poj答案全完整打包,给有需要的朋友
poj分类poj分类poj分类poj分类
POJ第1861题源码 POJ第1861题源码 POJ第1861题源码
北大POJ2002-Squares 解题报告+AC代码
poj 3414解题报告poj 3414解题报告poj 3414解题报告poj 3414解题报告
poj 1012解题报告poj 1012解题报告poj 1012解题报告poj 1012解题报告
poj 2329解题报告poj 2329解题报告poj 2329解题报告poj 2329解题报告
北大POJ1159-Palindrome 解题报告+AC代码
poj 1659解题报告poj 1659解题报告poj 1659解题报告poj 1659解题报告
NULL 博文链接:https://200830740306.iteye.com/blog/603493
POJ题解 个人写法 线段树每个人都不一样
poj 百练 题目分类 poj 百练 题目分类
poj2996代码,欢迎下载 下载,下载
POJ1083的代码,POJ1083的代码,POJ1083的代码
POJ 最接近点对问题 ACM北大 using namespace std; struct Point { float x; float y; };
poj2342,树形dp,dp[i][0]表示i不参加party,其下属(包括非直接下属)能得到的最优值。dp[i][1]表示i参加的其下属和他能得到的最优值。