Fork me on GitHub

清北学堂-贪心-bfs

输入样例:

 

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

 

  

 

输出样例:

 

40
60
90
70
90
8
30
70
100
10
9
81
63
1
4

 

  

 

数据范围:

思路:

让求和一个点联通的所有点的最大值

正解是tarjan,但是可以贪心,建反向边,从大到小排序一下,从最大的那个点宽搜,能扫到的更新他的值为起点的值(也就是这个点联通的最大值),把所有点更新后跳出,每次讯问时查询即可。。。。

注意标号在排序后会改变,另开个数组记录排序前每个标号对应的权值;

dfs  bfs 都可以。。。。

多组询问,注意每次数组清零。。。

代码:

bfs:

 

#include<cstdio>
#include<bits/stdc++.h>
#define MAXN 1000000
using namespace std;
int cnt,head[MAXN],T,n,m,k,ans[MAXN],tot,num[MAXN],pos,cnt1[MAXN];
int val[MAXN];
bool v[MAXN];
struct node{int to,nxt;}e[MAXN<<1];
struct node2{int val,id;}ee[MAXN<<1];
void add(int from,int to)
{
	e[++cnt].to=to;
	e[cnt].nxt=head[from];
	head[from]=cnt;
}
queue <int> q;
bool cmp(const node2 &a,const node2 &b) {return a.val>b.val;}
void bfs(int u)
{
	q.push(u);
	v[u]=1;
	pos++;
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		for(int i=head[x] ; i ; i=e[i].nxt)
		{
			int y=e[i].to;
			if(!v[y])
			{
				pos++;
				val[y]=val[u];
				v[y]=1;
				q.push(y);
			}
		}
	}
}
void init()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&ee[i].val);
		val[i]=ee[i].val;
		ee[i].id=i;
	}
	sort(ee+1,ee+n+1,cmp);
	for(int i=1;i<=n;i++)num[i]=ee[i].id;
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(y,x);
	}
	for(int i=1;i<=n;i++)
	{
		if(!v[num[i]])bfs(num[i]);
	}
	int a,u;
	for(int i=1;i<=k;i++)
	{
		scanf("%d%d",&a,&u);
		ans[++tot]=val[a]*u;
	}
}
void clear()
{
	memset(head,0,sizeof(head));
	memset(e,0,sizeof(e));
	memset(ee,0,sizeof(ee));
	memset(v,0,sizeof(v));
	memset(num,0,sizeof(num));
	memset(val,0,sizeof(val));
}
int main()
{
	#ifdef yilnr
	#else
	freopen("neural.in","r",stdin);
	freopen("neural.out","w",stdout);
	#endif
	scanf("%d",&T);
	while(T--)
	{
		init();
		for(int i=1;i<=k;i++) printf("%d\n",ans[i]);
		clear();
		tot=0;pos=0;
	}
	fclose(stdin);fclose(stdout);
	return 0;
}

 

  

 

dfs:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 400500
using namespace std;

inline int read() {
	int x = 0,f = 1;
	char s = getchar();
	while(s < '0' || s > '9') {if(s == '-') f = -1;s = getchar();}
	while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
	return x * f;
}

int T,n,m,k;
int head[N],cnt;
struct node {
	int nxt,to;
}e[N];
bool vis[N];
struct edge {
	int num,id;
	bool friend operator < (const edge &a,const edge &b) {
		return a.num > b.num;
	}
}tr[N];
long long sum[N];

inline void cp(int u,int v) {
	cnt ++;
	e[cnt].to = v;
	e[cnt].nxt = head[u];
	head[u] = cnt;
}

inline void dfs(int u,int top) {
	vis[u] = 1;
	for(int i = head[u]; i ; i = e[i].nxt) {
		int v = e[i].to;
		if(vis[v]) continue;
		sum[v] = sum[top];
		dfs(v,top);
	} 
}

inline void Work() {
	n = read(),m = read(),k = read();
	for(int i = 1;i <= n;i ++) tr[i].num = read(),tr[i].id = i,sum[i] = tr[i].num;
	for(int i = 1;i <= m;i ++) {
		int a = read(),b = read();
		cp(b,a);
	}
	sort(tr + 1,tr + n + 1);
	for(int i = 1;i <= n;i ++) 
		if(!vis[tr[i].id]) dfs(tr[i].id,tr[i].id);
	for(int i = 1;i <= k;i ++) {
		int a = read(),b = read();
		printf("%lld\n",sum[a] * b); 
	} 
}

inline void Clean() {
	memset(sum,0,sizeof(sum));
	memset(tr,0,sizeof(tr)); cnt = 0;
	memset(head,0,sizeof(head));
	memset(vis,0,sizeof(vis));
}

int main() {
	freopen("neural.in","r",stdin);
	freopen("neural.out","w",stdout);
	
	T = read();
	while(T --)
		Work(),Clean();
	return 0;
}

 

dfs来自清远学会

posted @ 2019-08-15 20:49  yelir  阅读(162)  评论(0)    收藏  举报