dfs4

【rest】搜索练习二

农场中,由于奶牛数量的迅速增长,通往奶牛宿舍的道路也出现了严重的交通拥堵问题.FJ打算找出最忙碌的道路来重点整治. 这个牧区包括一个由M (1 ≤ M ≤ 50,000)条单行道路(有向)组成的网络,以及 N (1 ≤ N ≤ 5,000)个交叉路口(编号为1..N),每一条道路连接两个不同的交叉路口.奶牛宿舍位于第N个路口.每一条道路都由编号较小的路口通向编号较大的路口.这样就可以避免网络中出现环.显而易见,所有道路都通向奶牛宿舍.而两个交叉路口可能由不止一条边连接. 在准备睡觉的时候,所有奶牛都从他们各自所在的交叉路口走向奶牛宿舍,奶牛只会在入度为0的路口,且所有入度为0的路口都会有奶牛. 帮助FJ找出最忙碌的道路,即计算所有路径中通过某条道路的最大次数.答案保证可以用32位整数存储.

第一行:两个用空格隔开的整数:N,M.

第二行到第M+1行:每行两个用空格隔开的整数ai,bi,表示一条道路从ai到bi.

第一行: 一个整数,表示所有路径中通过某条道路的最大次数.

输入:

10 9
1 10
2 10
3 10
4 10
5 10
6 10
7 10
8 10
9 10

输出:

1

建正反两图,f[i]表示节点i到n的路径数,g[i]表示节点i到入度为零的节点的路径数,答案为正向图中每条道路g[左端点]*f[右端点]的最大值。

#include <stdio.h>

#include <iostream>

#include <cstring>

#include <algorithm>

#include <cmath>

#include <vector>

using namespace std;

vector <int> a[5005],b[5005];

int f[5005],g[5005];

int i,j,t,n,m,l,r,k,z,y,x,ans;

inline int read()

{

int x=0;char ch=getchar();

while (ch<‘0‘ || ch>‘9‘) ch=getchar();

while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();

return x;

}

void dfs(vector <int> *G,int *F,int s)

{

int i,j,t;

if (G[s].size()==0)

{

F[s]=1;

return ;

}

for (i=0;i<G[s].size();i++)

{

t=G[s][i];

if (F[t]==0) dfs(G,F,t);

F[s]+=F[t];

}

}

int main()

{

memset(f,0,sizeof(f));memset(g,0,sizeof(g));

n=read();m=read();

for (i=1;i<=m;i++)

{

x=read();y=read();

if (x>y) swap(x,y);

a[x].push_back(y);b[y].push_back(x);

}

for (i=1;i<=n;i++) if (f[i]==0) dfs(a,f,i);

for (i=n;i>=1;i--) if (g[i]==0) dfs(b,g,i);

ans=0;

for (i=1;i<n;i++) for (j=0;j<a[i].size();j++) ans=max(ans,g[i]*f[a[i][j]]);

printf("%d\n",ans);

return 0;

}

时间: 2024-10-10 05:37:05

dfs4的相关文章

BZOJ3607 : 数据网络

首先答案一定是包含直径某个端点的一个连通块里所有边权值之和,设直径为$AB$,以$A$和$B$分别为根进行处理. 首先按照最长路法则将这棵树进行树链剖分,那么每个叶子的贡献为它与它所在链顶端的点的距离. 将叶子按贡献从大到小排序,并求出$h[x]$表示$x$子树内叶子排名的最小值. 对于询问$(x,k)$,需要取$2k-1$个叶子. 如果$h[x]\leq k$,那么说明前$2k-1$个叶子形成的连通块经过了$x$点,直接返回前$2k-1$个叶子的贡献和即可. 否则对于一个选中的叶子$y$,如果

HDU 3368 Reversi

Reversi Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1364    Accepted Submission(s): 540 Problem Description Reversi, also called Othello, is a two-sided game.Each of the two sides correspond

Noip2016滚粗记QAQ

day1 t1 XBG #include<map> #include<cstdio> #include<string> #include<string.h> #include<iostream> #include<algorithm> using namespace std; int d[123456]; char ty[123456][20]; int n,m; //... int main(){ freopen("toy

LeetCode: Validate Binary Search Tree 解题报告

Validate Binary Search Tree Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key.The right subtree of a node co

hdu 4871 树的分治+最短路记录路径

/* 题意:给你一些节点和一些边,求最短路径树上是k个节点的最长的路径数. 解:1.求出最短路径树--spfa加记录 2.树上进行操作--树的分治,分别处理子树进行补集等运算 */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> #include<iostream> #include<queue> #define ll __int6

bzoj3743 [Coci2015]Kamp 常州模拟赛d6t2

3743: [Coci2015]Kamp Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 484  Solved: 229[Submit][Status][Discuss] Description 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的点)要集中到一个点举行聚会. 聚会结束后需要一辆车从举行聚会的这点出发,把这K个人分别送回去. 请你回答,对于i=1~n,如果在第i个点举行聚会,司

7.30考试(第一发博文)

第一篇博文献给NOIP2015斗地主. 这道题为NOIP2015第一天第三题.属于爆搜类,没有任何算法,就是模拟加爆搜.由于有不同种打法,dfs分为好几层,本着先大后小便于剪枝的原则,先出顺子,再带牌,最后散着出. 首先,花色对结果无影响,其次大小王对结果是否有贡献只看是否出现其中之一,出现结果+1即可,未出现就不必管了(吐槽一下题目描述,没说四带二不算俩王,但测试点中确实不带).还有一点值得注意的是大小顺序,首先是2不算顺子,其次1比3~13都大,因此可以把大小统一减2,1.2改为12.13便

BZOJ4065 : [Cerc2012]Graphic Madness

因为两棵树中间只有k条边,所以这些边一定要用到. 对于每棵树分别考虑: 如果一个点往下连着两个点,那么这个点往上的那条边一定不能用到. 如果一个点往下连着一个点,那么这个点往上的那条边一定不能用到. 否则一定无解. 这样求出所有一定要用到的边后,如果不存在奇点且这个图是个连通图的话,那么就有解.时间复杂度$O(n+m+k)$. #include<cstdio> #include<cstring> #define N 10010 int T,k,n,m,i,d[N],vis[N],g

bzoj 3743

这道题用到了4个dfs,分别是找出所有家的最小生成树,找出一点距离树的最小距离,找出每个点儿子距离的最大值(不包括父亲,也就是指不包括根节点的子树),用父亲的值来更新自己 因为我们可以知道:如果我们在树上,那么最短的距离就是树的长度的两倍-距自己最远的点的距离,当我们不在树上时,就得先走到树上(这条路径是唯一的),然后再重复刚才的过程 找出生成树比较简单,重点是找出距树上一点最远的点的距离,这里先找出除了父亲之外每个子树的距离,求出最大和第二,然后再用父亲更新自己的距离,很难想到 #includ