比特跳跃

题目链接

  • 这次真的是差五分钟就能过掉这题了,好可惜呀
  • 二进制数位的包含关系构成一(张有向无环图,2024.8.12更正),我们可以在这(张有向无环图)上DP来统计一些信息
  • 在树状数组中,c[x]管辖的区间是[x-lowbit(x)+1,x]
  • 十五分钟加上这样一个DP,未必来不及。只是,越到时间紧张的关头,越要屏蔽其他念想的干扰,告诉自己不去管时间,把注意力集中在代码的编写上
  • 如果你写完代码能一遍过,那时间往往是来得及的
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int n,m;
vector<int>a[100005];
vector<int>c[100005];
priority_queue<pair<long long,int> >q;
long long d[100005],g[100005];
bool f[100005];
int read1()
{
	char cc=getchar();
	while(!(cc>=48&&cc<=57))
	{
		if(cc=='-')
		{
			break;
		}
		cc=getchar();
	}
	bool f=false;
	int s=0;
	if(cc=='-')
	{
		f=true;
	}
	else
	{
		s=cc-48;
	}
	while(1)
	{
		cc=getchar();
		if(cc>=48&&cc<=57)
		{
			s=s*10+cc-48;
		}
		else
		{
			break;
		}
	}
	if(f==true)
	{
		s=-s;
	}
	return s;
}
void dijkstra()
{
	int cnt=0;
	while(cnt<n&&!q.empty())
	{
		int p=q.top().second;
		long long va=-q.top().first;
		q.pop();
		if(f[p]==true||va!=d[p])
		{
			continue;
		}
		f[p]=true;
		cnt++;
		for(int i=0;i<a[p].size();i++)
		{
			if(d[p]+c[p][i]<d[a[p][i]])
			{
				d[a[p][i]]=d[p]+c[p][i];
				q.push(make_pair(-d[a[p][i]],a[p][i]));
			}
		}
	}
}
long long dp(int x)
{
	if(g[x]!=-1)
	{
		return g[x];
	}
	if(x==(x&(-x)))
	{
		return g[x]=d[x];
	}
	long long minn=LLONG_MAX;
	for(int i=0;i<17;i++)
	{
		if(((x>>i)&1)==1)
		{
			minn=min(minn,dp(x&(~(1<<i))));
		}
	}
	return g[x]=minn;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		long long k;
		cin>>n>>m>>k;
		while(!q.empty())
		{
			q.pop();
		}
		for(int i=1;i<=n;i++)
		{
			a[i].clear();
			c[i].clear();
			f[i]=false;
			d[i]=LLONG_MAX;
			g[i]=-1;
		}
		for(int i=1;i<=m;i++)
		{
			int u,v,w;
			u=read1();
			v=read1();
			w=read1();
			a[u].push_back(v);
			a[v].push_back(u);
			c[u].push_back(w);
			c[v].push_back(w);
		}
		d[1]=0;
		q.push(make_pair(-d[1],1));
		dijkstra();
		for(int i=1;i<=n;i++)
		{
			dp(i);
		}
		while(!q.empty())
		{
			q.pop();
		}
		d[1]=0;
		q.push(make_pair(-d[1],1));
		f[1]=false;
		for(int i=2;i<=n;i++)
		{
			f[i]=false;
			if(g[i]!=LLONG_MAX)
			{
				d[i]=min(g[i]+k*i,k*(1|i));
			}
			else
			{
				d[i]=k*(1|i);
			}
			q.push(make_pair(-d[i],i));
		}
		dijkstra();
		for(int i=2;i<=n;i++)
		{
			printf("%lld ",d[i]);
		}
		cout<<endl;
	}
	return 0;
}
posted @ 2024-07-26 19:51  D06  阅读(58)  评论(0编辑  收藏  举报