ARROW+粗略实现

#include
#define LL long long
#define M(a) memset(a,0,sizeof a) 
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
const int mxn=10005;
int n,m,s,cnt,len,num;
struct edge
{
	int w,to,nxt;
}e[1000005];
queue  q;
vector  E[mxn],we[mxn];
vector  Z[mxn],wz[mxn];
int head[mxn],dis[mxn];
int dis1[mxn],dis2[mxn];
bool vis1[mxn],vis2[mxn];
void add(int u,int v,int w)
{
	e[++cnt].to=v,e[cnt].w=w,e[cnt].nxt=head[u],head[u]=cnt;
}
void calc()
{
	num=ceil(3*pow((double)n*n*log(n),1.0/3.0));
	rep(Case,1,500)
	{
		rep(i,1,n) dis[i]=1e9;
		int u=rand()%n+1;
		q.push(u);
		dis[u]=0;
		while(!q.empty())
		{
			u=q.front();
			q.pop();
			for(int i=head[u];i;i=e[i].nxt)
			{
				int v=e[i].to;
				if(dis[v]==1e9) q.push(v);
				dis[v]=min(dis[v],dis[u]+e[i].w);
			}
		}
		rep(i,1,n) if(dis[i]!=1e9) len=max(len,dis[i]);
	}
	len=len*3/2;
//	printf("num=%d\n",num);
//	printf("len=%d\n",len);
}
void ARROW(int s,int t)
{
	M(vis1),M(vis2); 
	memset(dis1,0x3f,sizeof dis1);
	memset(dis2,0x3f,sizeof dis2);
	rep(i,1,num)
	{
		int u=s;
		vis1[u]=1;
		dis1[u]=0;
		rep(j,1,len)
		{
			int sz=E[u].size();
			if(sz==0) break;
			int index=rand()%sz;
			int v=E[u][index];
			dis1[v]=min(dis1[v],dis1[u]+we[u][index]);
			vis1[v]=1;
			u=v;
		}
	}
	rep(i,1,num)
	{
		int u=t;
		vis2[u]=1;
		dis2[u]=0;
		rep(j,1,len)
		{
			int sz=Z[u].size();
			if(sz==0) break;
			int index=rand()%sz;
			int v=Z[u][index];
			dis2[v]=min(dis2[v],dis2[u]+wz[u][index]);
			vis2[v]=1;
			u=v;
		}
	}
	int ans=1e9;
	rep(i,1,n) if(vis1[i] && vis2[i])
		ans=min(ans,dis1[i]+dis2[i]);
	printf("%d ",ans);
}
int main()
{
	srand(time(0));
	scanf("%d%d%d",&n,&m,&s);
	rep(i,1,m)
	{
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
		E[u].push_back(v);
		we[u].push_back(w);
		Z[v].push_back(u);
		wz[v].push_back(w);
	}
	calc();
	rep(t,1,n)
	{
		ARROW(s,t);
	}
	return 0;
}

你可能感兴趣的:(杂)