↓ Skip to main content
  1. Posts/

poj 1985 Cow Marathon (树的直径模板题)

·728 words·2 mins
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

poj1985 题意:求树上两点的最长距离。。。也就是传说中的树的直径。。。

思路: 两遍BFS :先任选一个起点BFS找到最长路的终点,再从终点进行BFS,则第二次BFS找到的最长路即为树的直径; 原理: 设起点为u,第一次BFS找到的终点v一定是树的直径的一个端点 证明: 1) 如果u 是直径上的点,则v显然是直径的终点(因为如果v不是的话,则必定存在另一个点w使得u到w的距离更长,则于BFS找到了v矛盾) 2) 如果u不是直径上的点,则u到v必然于树的直径相交(反证),那么交点到v 必然就是直径的后半段了 所以v一定是直径的一个端点,所以从v进行BFS得到的一定是直径长度

参考博客

实际写的时候,第一次bfs最后一个出队的点就是直径的一个端点。。。 好像错了。。。还是稳妥一点。。。最后扫一遍。。距离最远的一定是端点。。。 然后因为题目没有数据范围。。。?re多次orz。。。

代码实现
  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年07月12日 星期二 11时26分41秒
  4File Name :code/poj/1985.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=4E4+5;
 34int n,m;
 35vector < pi >edge[N];
 36int d[N];
 37int lst;
 38int ans;
 39bool vis[N];
 40
 41void bfs( int s)
 42{
 43    ms(vis,false);
 44    ms(d,0x3f);
 45
 46    queue<int>q;
 47    q.push(s);
 48    d[s] = 0 ;
 49    vis[s] = true;
 50
 51    while (!q.empty())
 52    {
 53	int u = q.front(); q.pop();
 54	int siz = edge[u].size();
 55	lst = u ;
 56
 57	for ( int i = 0 ; i < siz;  i++)
 58	{
 59	    int v = edge[u][i].fst;
 60	    if (vis[v]) continue;
 61	    vis[v] = true;
 62	    d[v] = d[u] + edge[u][i].sec;
 63	    ans = max(ans,d[v]);
 64	    q.push(v);
 65	}
 66    }
 67    int mx = 0;
 68 /*   for ( int i = 1 ; i <= n ; i++)
 69    {
 70	if (d[i]>mx)
 71	{
 72	    mx = d[i];
 73	    lst = i ;
 74	}
 75    }  */
 76
 77}
 78int main()
 79{
 80	#ifndef  ONLINE_JUDGE
 81	freopen("code/in.txt","r",stdin);
 82  #endif
 83	cin>>n>>m;
 84	for ( int i = 1 ; i <= n ; i++) edge[i].clear();
 85	for ( int i = 1 ; i <= m ; i++)
 86	{
 87	    int u,v,w;
 88	    char dir;
 89	    scanf("%d %d %d %c",&u,&v,&w,&dir); //dir这东西有用?
 90	    edge[u].push_back(make_pair(v,w));
 91	    edge[v].push_back(make_pair(u,w));
 92	}
 93
 94	ans = inf;
 95	bfs(1);
 96	ans = 0;
 97//	cout<<"lst:"<<lst<<endl;
 98	bfs(lst);
 99	cout<<ans<<endl;
100  #ifndef ONLINE_JUDGE
101  fclose(stdin);
102  #endif
103    return 0;
104}

Related

ural 1416. Confidential (次小生成树模板题)

·730 words·2 mins
URAL1416 题意:次小生成树模板题 思路:用Kruskal求最小生成树,标记用过的边。求次小生成树时,依次枚举用过的边,将其去除后再求最小生成树,得出所有情况下的最小的生成树就是次小的生成树。复杂度o(m2)。。。貌似有其他优化。。。

BZOJ 1681: [Usaco2005 Mar]Checking an Alibi 不在场的证明 (spfa)

·1064 words·3 mins
1681: [Usaco2005 Mar]Checking an Alibi 不在场的证明 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 250 Solved: 178 [Submit][Status][Discuss] Description # A crime has been comitted: a load of grain has been taken from the barn by one of FJ’s cows. FJ is trying to determine which of his C (1 <= C <= 100) cows is the culprit. Fortunately, a passing satellite took an image of his farm M (1 <= M <= 70000) seconds before the crime took place, giving the location of all of the cows. He wants to know which cows had time to get to the barn to steal the grain. Farmer John’s farm comprises F (1 <= F <= 500) fields numbered 1..F and connected by P (1 <= P <= 1,000) bidirectional paths whose traversal time is in the range 1..70000 seconds (cows walk very slowly). Field 1 contains the barn. It takes no time to travel within a field (switch paths). Given the layout of Farmer John’s farm and the location of each cow when the satellite flew over, determine set of cows who could be guilty. NOTE: Do not declare a variable named exactly ’time’. This will reference the system call and never give you the results you really want.

poj 2342 Anniversary party (基础树形dp)

·634 words·2 mins
题目链接 题意:n个人的上下级关系形成一棵树..每一个人有一个val(可正可负),要选若干个人参加一个party,要求是一个人和他的直接上级不能同时在场。问参加party的人最大的val之和。

华科软院计组概念复习

·2489 words·5 mins
noip 初赛加强版既视感… 自己手动整理的 第二章 机器数:正负符号数码化后的数据称为机器数。 BCD 码:用二进制编码的十进制数称为 BCD 码。 有权码:每位二进制数码元都有确定权值的编码。 校验码:为了发现或纠正数据传送中出现错误的编码。 浮点数的精度由尾数的位数决定。 第三章 溢出:运算结果超出了机器能表示的数据范围。 溢出的特征:结果的符号与操作数的符号不同。 变形补码:两个符号位的补码(用来检测溢出,00,11说明没有溢出,10,01说明有溢出) 对阶:使阶码相等的过程(原则是小阶码向大阶码看齐) 结果规格化:将非规格化数处理为规格化形式。

codeforces 660 C. Hard Process (ruler)

·321 words·1 min
cf660C solution:ruler.1A 代码实现 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月08日 星期三 23时43分18秒 4File Name :code/cf/problem/660C.cpp 5************************************************ */ 6 7#include <cstdio> 8#include <cstring> 9#include <iostream> 10#include <algorithm> 11#include <vector> 12#include <queue> 13#include <set> 14#include <map> 15#include <string> 16#include <cmath> 17#include <cstdlib> 18#include <ctime> 19#define fst first 20#define sec second 21#define lson l,m,rt<<1 22#define rson m+1,r,rt<<1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair < int ,int > 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E5+7; 34int n,k; 35int sum[N],a[N]; 36 37void ruler() 38{ 39 int head = 1; 40 int tail = 1; 41 int l,r; 42 int res = -1; 43 int cnt = 0 ; 44 45 while (tail<=n) 46 { 47 while (a[tail]==1) tail++; 48// cout<<"head:"<<head<<" tail:"<<tail<<endl; 49 if (a[tail]==0&&tail<=n) cnt++; 50 51 while (sum[tail]-sum[head-1]<=k&&tail<=n) tail++; 52// cout<<"head:"<<head<<"tail:"<<tail<<endl; 53 if (tail-head>res) 54 { 55 res = tail-head; 56 // cout<<"res:"<<res<<endl; 57 l = head; 58 r = tail-1; 59 } 60 61 while (head<=tail&&sum[tail]-sum[head-1]>k) head++; 62// cout<<"head::"<<head<<" tail:"<<tail<<endl; 63 if (tail<=n&&tail-head+1>res) 64 { 65 res = tail-head+1; 66 l = head; 67 r = tail; 68 } 69 70 71 } 72 73 74 for ( int i = l ; i <= r ; i++) a[i] = 1; 75 76 cout<<res<<endl; 77 for ( int i = 1 ; i <= n ; i++) cout<<a[i]<<" "; 78} 79int main() 80{ 81 #ifndef ONLINE_JUDGE 82 freopen("code/in.txt","r",stdin); 83 #endif 84 85 cin>>n>>k; 86 87 sum[0] = 0; 88 for ( int i = 1; i <= n ; i++) 89 { 90 scanf("%d",&a[i]); 91 sum[i] = sum[i-1] +(1-a[i]); 92 } 93 94 ruler(); 95 96 97 #ifndef ONLINE_JUDGE 98 fclose(stdin); 99 #endif 100 return 0; 101}