csp模拟赛5加减法--宽搜维护联通快
Posted yelir
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csp模拟赛5加减法--宽搜维护联通快相关的知识,希望对你有一定的参考价值。
题目大意:
一开始想用并查集,发现很难维护联通块的代表元素,所以用了宽搜,开数组会炸,所以开一个优先队列维护,每扫完一个联通块,统计答案,清空优先队列,!!千万记住注意数组的大小!!!
代码:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<queue>
#define int long long
#define N 1005000
using namespace std;
int n,m,l,val[N],head[N],cnt,tot,ans;
int siz[N];
bool vis[N];
struct nodeint to,nxt;e[N];
int read()
int x=0,f=1;
char ch=getchar();
while(ch<‘0‘||ch>‘9‘)if(ch==‘-‘)f=-1;ch=getchar();
while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘;ch=getchar();
return x*f;
void add(int from,int to)
e[++cnt] = (node)to,head[from];
head[from]=cnt;
queue<int> q;
priority_queue <int> dij;
void bfs(int x)
vis[x]=1;
int siz=0;
siz+=(val[x]-1);
ans+=x;
dij.push(x);
q.push(x);
while(!q.empty())
int s=q.front();
q.pop();
for(int i=head[s];i;i=e[i].nxt)
int y=e[i].to;
if(!vis[y])
vis[y]=1;
q.push(y);
siz+=(val[y]-1);
dij.push(y);
ans+=y;
while(siz)
int xx=dij.top(); dij.pop();
if(siz<=l-1)
ans+=siz*xx;
siz=0;
if(siz>(l-1))
siz-=(l-1);
ans+=xx*(l-1);
while(dij.size()) dij.pop();
signed main()
#ifdef yilnr
#else
freopen("pmlaw.in","r",stdin);
freopen("pmlaw.out","w",stdout);
#endif
n=read();m=read();l=read();
for(int i=1;i<=n;i++)val[i]=read();
for(int i=1,x,y;i<=m;i++)
scanf("%lld%lld",&x,&y);
add(x,y);add(y,x);
for(int i=1;i<=n;i++)if(!vis[i])bfs(i);
printf("%lld\\n",ans);
fclose(stdin);fclose(stdout);
return 0;
以上是关于csp模拟赛5加减法--宽搜维护联通快的主要内容,如果未能解决你的问题,请参考以下文章