LOJ10064 Dark Castle

Title Link https://ajax.loj.ac/problem/10064

Meaning: give you n points, m edges, and connect any selected edges. It is a legal scheme to ensure that the shortest path from point 1 to any point after connecting the edges is the same as that from point 1 to that point after connecting all m edges. The number of schemes was counted and 31 times - 1 of 2 was modeled.

Solution: this question is really a comparative metaphysics. Let's run dijkstra on one side and find the shortest path from point 1 to any point. Then we sort the dis value from small to large, and then use the idea of prim to enumerate and add the nodes to the T-set. If the p-node satisfies dis[p]=dis[x]+v[x][p](v is the length of the edge, X is in the T-set), then the number of schemes in the current step is + 1. Finally, we get the result through the multiplication principle.

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define pr pair < int , int >
using namespace std;
priority_queue< pr, vector< pr > , greater< pr > > q;
const long long mo=(1LL<<31)-1;
int cnt,n,m,head[2000000],nxt[2000000],to[2000000],val[2000000],p[2000000],vis[2000000],dis[1000005];
bool f[2000000];
struct xy{
	int dis,id;
}e[2000000];
bool cmp(xy x,xy y)
{
	return x.dis<y.dis;
}
void add(int x,int y,int z)
{
	cnt++;nxt[cnt]=head[x];to[cnt]=y;val[cnt]=z;head[x]=cnt;
}
void dijkstra()
{
	for (int i=1;i<=n;i++) e[i].dis=1000000000;
	memset(vis,0,sizeof(vis));
	e[1].dis=0;
	q.push(make_pair(0,1));
	while (q.size())
	{
		int x=q.top().second;q.pop();
		if (vis[x]) continue;
		vis[x]=1;
		for (int i=head[x];i;i=nxt[i])
		{
			int y=to[i],z=val[i];
			if (e[y].dis>e[x].dis+z) {e[y].dis=e[x].dis+z;q.push(make_pair(e[y].dis,y));}
		}
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	int x,y,z;
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);
		add(y,x,z);
	}
	dijkstra();
	for (int i=1;i<=n;i++) e[i].id=i,dis[i]=e[i].dis;
	sort(e+1,e+n+1,cmp);
	memset(f,false,sizeof(f));
	f[1]=true;
	for (int i=2;i<=n;i++)
	{
		f[e[i].id]=true;
		for (int j=head[e[i].id];j;j=nxt[j])
		{
			y=to[j];
			if (f[y] && dis[y]+val[j]==e[i].dis) p[i]++;
		}
	}
	long long ans=1;
	for (int i=2;i<=n;i++)
		ans=(ans*p[i])%mo;
	printf("%lld\n",ans);
}

 

Posted by zulfer on Mon, 30 Dec 2019 09:50:08 -0800