BZOJ-3040 最短路

最短路+堆优化。

普通的堆还不行,自己用的是配对堆(貌似斐波那契堆也行?毕竟理论复杂度)

然后发现自己的配对堆比云神的不知快了多少。。。我照着他的模版打的喂。。

然后发现前T条边不理都能A。。。

数据啊数据233

#include <cctype>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define ll long long 
#define maxn 1000009
#define maxm 10000009
using namespace std;
const ll inf=(ll)(0x7fffffff)*(ll)(0x7fffffff);
inline ll read()
{
	ll x=0; char ch=getchar();
	while (!isdigit(ch)) ch=getchar();
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x;
}
struct edge{int y, z; edge *n;} e[maxm], *fir[maxn], *pt=e;
inline void Add(ll x, ll y, ll z){pt->y=y, pt->z=z, pt->n=fir[x], fir[x]=pt++;}
struct node{int l, r, ch; node(){l=r=ch;}} h[maxn];

int n, m;
ll d[maxn]; bool f[maxn];

int roof=0;
int join(int v, int u)
{
	if (d[v]<d[u]) swap(v, u);
	h[v].l=u, h[v].r=h[u].ch, h[h[u].ch].l=v;
	h[u].ch=v;
	return u;
}
void push(int v){if (!roof) roof=v; else roof=join(roof, v);}
void update(int v)
{
	if (v!=roof)
	{
		if (h[h[v].l].ch==v)
			h[h[v].l].ch=h[v].r;
		else 
			h[h[v].l].r=h[v].r;
		if (h[v].r) h[h[v].r].l=h[v].l;
		h[v].l=h[v].r=0;
		roof=join(roof, v);
	}
}
int st[maxn], top;
void pop()
{
	if (!h[roof].ch) roof=0; else 
	{
		top=0; int t=h[roof].ch;
		while (t) if (h[t].r)
		{
			int k=h[h[t].r].r;
			int v=h[t].r;
			h[t].l=h[t].r=h[v].l=h[v].r=0;
			st[++top]=join(t, v);
			t=k;
		}
		else 
		{
			st[++top]=t; h[t].l=h[t].r=0; break;
		}
		roof=st[top];
		rep(i, 1, top-1) roof=join(roof, st[i]);
	}
}


void Dijstra()
{
	clr(f, 0); d[1]=0; rep(i, 2, n) d[i]=inf; push(1); f[1]=true;
	rep(i, 1, n)
	{
		int x=roof; pop(); f[x]=0;
		if (x==n) break;
		travel(x) if (d[p->y]>d[x]+(ll)(p->z))
		{
			d[p->y]=d[x]+(ll)(p->z);
			if (!f[p->y]) push(p->y), f[p->y]=1; else update(p->y);
		}
	}
}
int main()
{
	n=read(), m=read();
	ll t=read(), rxa=read(), rxc=read(), rya=read(), ryc=read(), rp=read(), x, y, a, b;
	/* rep(i, 1, t)
	{
		x=(x*rxa+rxc)%rp;
		y=(y*rya+ryc)%rp;
		a=min(x%n+1, y%n+1);
		b=max(y%n+1, y%n+1);
		Add(a, b, 1e8-100*a);
	} */
	rep(i, 1, m-t){x=read(), y=read(); Add(x, y, read());}
	Dijstra();
	printf("%lld\n", d[n]);
	return 0;
}
posted @ 2015-05-05 15:21  NanoApe  阅读(261)  评论(0编辑  收藏  举报
AmazingCounters.com