关于次短路[已过!]求hack/证明正确性
查看原帖
关于次短路[已过!]求hack/证明正确性
989997
DGL__DGL_AFO楼主2024/10/13 18:40

首先数据貌似很水

大体思路为找到最短路上每一条边,然后枚举每条边不能走.

发现会被样例2卡飞,于是再找到在最短路上的点连出的最短的一条边额外走两遍

然后过了...(理论来说是 O(nmlogm)O(nmlogm) 的复杂度,加了点小优化(唐杰斯特拉))

然而这个思路的正确性是否能证明/证伪,求各位大佬解答

以下是代码和一些手造的数据

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,k;
int h[5145],e[214514],ne[214514],idx;
ll w[214514],d[5145];
int st[5145],op[5145];
ll ans=1e18;
ll gen,dgl,minn=1e18;
int cnt;
int pre[5145],fg=1,res[5145];
map<pair<int,int>,int> un;
priority_queue<pair<int,int> >q;

inline void add(int a,int b,int c)
{
	ne[idx]=h[a];
	e[idx]=b;
	w[idx]=c;
	h[a]=idx;
	idx++;
}

inline void dijk()
{
	memset(d,0x3f,sizeof d);
	//cout<<d[0];
	memset(st,0,sizeof st);
	d[1]=0;
	q.push(make_pair(0,1));
	
	while(q.size())
	{
		int x=q.top().second;
		if(x==n)
		  break;
		q.pop();
		if(st[x])
		  continue ;
		st[x]=1;  
		for(int i=h[x];~i;i=ne[i])
		{
			int y=e[i];
			if((op[y]>=k||y==n)&&d[y]>d[x]+w[i])
			{
				d[y]=d[x]+w[i];
				pre[y]=i;
				q.push(make_pair(-d[y],y));
			}
		}
	}
	while(q.size())
	  q.pop();
}

int main()
{
	
	memset(h,-1,sizeof h);
	cin>>n>>m>>k;
	for(int i=1;i<=m;i++)
	{
		int a,b,c;
		cin>>a>>b>>c;
		if(a>b)
		  swap(a,b);
		if(un[make_pair(a,b)]==0)
		{
			un[make_pair(a,b)]=1;
			op[a]++;
		  op[b]++;
		}
		add(a,b,c);
		add(b,a,c);
	}
	//pre[1]=-1;
	dijk();
	dgl=d[n];
	//cout<<ans;
	if(dgl>=1e15)
	{
		cout<<-1;
		return 0;
	}
	else
	{
		for(int i=h[1];~i;i=ne[i])
		  minn=min(minn,w[i]);
		for(int i=n;i!=1;i=e[i])
		{
			for(int j=h[i];~j;j=ne[j])
			  minn=min(minn,w[j]);
			i=pre[i]^1;//cout<<i<<' ';
			res[++cnt]=i;		
		}
		//
    ans=dgl+minn+minn;
		//cout<<ans<<' ';
		for(int i=1;i<=cnt;i++)
		{
			gen=w[res[i]];
			w[res[i]]=1e9;
			w[res[i]^1]=1e9;
			dijk();
			w[res[i]]=gen;
			w[res[i]^1]=gen;
			if(d[n]!=dgl)
			  ans=min(ans,d[n]);
		}
	}  
	/*if(ans>=1e15)
	  cout<<-1;
	else*/
	cout<<ans;
	return 0;
}
/*
4 4 3
2 1 100
2 4 200
2 3 250
3 4 100
*/
/*
4 3 1
1 2 5000
2 4 5000
2 3 100
*/
/*
4 4 1
1 2 100
2 4 200
2 3 250
3 4 100
*/
/*
4 4 1
1 2 5000
2 4 5000
2 3 100
1 4 10010
*/
/*
4 4 1
1 2 5000
2 4 5000
1 3 1000
3 4 9000
*/
/*
4 3 1
1 2 11
2 3 45
3 1 14
*/
/*
3 2 1
1 3 114514
1 2 1
*/
2024/10/13 18:40
加载中...