bzoj4400: tjoi2012 桥

先传代码再填坑

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#define N 100005
#define M 400005
#define INF 0x7FFFFFFF

using namespace std;
inline int read(){
	int ret=0;char ch=getchar();
	while (ch<'0' || ch>'9') ch=getchar();
	while ('0'<=ch && ch<='9'){
		ret=ret*10-48+ch;
		ch=getchar();
	}
	return ret;
}

struct STnode{
	int l,r;
	int tag;
};

int a[N];
struct SegmentTree{
	STnode t[4*N];
	void PushDown(int x){
		if (t[x].l==t[x].r) return;
		if (t[x].tag==INF) return;
		t[x<<1].tag=min(t[x<<1].tag,t[x].tag);
		t[x<<1^1].tag=min(t[x<<1^1].tag,t[x].tag);
		t[x].tag=INF;
	}
	void build(int x,int l,int r){
		t[x].l=l;t[x].r=r;t[x].tag=INF;
		if (l==r) return;
		int mid=(l+r)/2;
		build(x<<1,l,mid);
		build(x<<1^1,mid+1,r);
	}
	void modify(int x,int l,int r,int value){
		PushDown(x);
		if (l<=t[x].l&&t[x].r<=r){
			t[x].tag=min(t[x].tag,value);
			return;
		}
		int mid=(t[x].l+t[x].r)/2;
		if (l<=mid) modify(x<<1,l,r,value);
		if (r>mid) modify(x<<1^1,l,r,value);
	}
	int getans(int x){
		if (t[x].l==t[x].r){a[t[x].l]=t[x].tag;return t[x].tag;}
		PushDown(x);
		return max(getans(x<<1),getans(x<<1^1));
	}
} st;


struct edge{
	int adj,next,len;
	int id;
	edge(){}
	edge(int _adj,int _next,int _len):adj(_adj),next(_next),len(_len){}
} e[M];
int n,g[N],m;
void AddEdge(int u,int v,int w){
	e[++m]=edge(v,g[u],w);g[u]=m;
}


struct HeapNode{
	int pos,value;
	HeapNode(){}
	HeapNode(int _pos,int _value):pos(_pos),value(_value){}
};
bool operator >(const HeapNode &x,const HeapNode &y){
	return x.value>y.value;
}
priority_queue<HeapNode,vector<HeapNode> ,greater<HeapNode> > h;

int fa[N];
int mind[N];
bool flag[N];
int from[N];
void dijkstra(int _s){
	memset(mind,127,sizeof(mind));
	memset(flag,0,sizeof(flag));
	h.push(HeapNode(_s,mind[_s]=0));
	fa[_s]=from[_s]=0;
	while (!h.empty()){
		int u=h.top().pos;
		h.pop();
		flag[u]=1;
		for (int i=g[u];i;i=e[i].next){
			int v=e[i].adj;
			if (mind[v]>mind[u]+e[i].len){
				mind[v]=mind[u]+e[i].len;
				h.push(HeapNode(v,mind[v]));
				fa[v]=u;from[v]=i;
			}
		}
		while (!h.empty()&&flag[h.top().pos]) h.pop();
	}
}

int deep[N];
void dfs(int u){
	for (int i=g[u];i;i=e[i].next){
		int v=e[i].adj;
		if (!deep[v]) deep[v]=deep[u];
		dfs(v);
	}
}

void rebuild(){
	memset(deep,0,sizeof(deep));
	deep[n]=1;
	for (int i=n;fa[i];i=fa[i]) deep[fa[i]]=deep[i]+1;
	memset(g,0,sizeof(g));m=1;
	for (int i=2;i<=n;++i) AddEdge(fa[i],i,0);
	dfs(1);
}


int u[M],v[M],w[M];
int dist[N];

int main(){
	n=read();int m0=read();
	memset(g,0,sizeof(g));m=1;
	for (int i=1;i<=m0;++i){
		u[i]=read();v[i]=read();w[i]=read();
		AddEdge(u[i],v[i],w[i]);e[m].id=i;
		AddEdge(v[i],u[i],w[i]);e[m].id=i;
	}
	dijkstra(n);
	for (int i=1;i<=n;++i) dist[i]=mind[i];
	dijkstra(1);
	for (int i=2;i<=n;++i) w[e[from[i]].id]=0;
	rebuild();
	st.build(1,1,deep[1]-1);
	for (int i=1;i<=m0;++i)if (w[i]){
		if (deep[u[i]]>deep[v[i]]) swap(u[i],v[i]);
		int x=deep[u[i]],y=deep[v[i]];
		if (x==y) continue;
		st.modify(1,x,y-1,dist[u[i]]+w[i]+mind[v[i]]);
	}
	int ans=st.getans(1),cnt=0;
	for (int i=1;i<deep[1];++i) cnt+=(a[i]==ans);
	printf("%d %d\n",ans,ans==mind[n]?m0:cnt);
	return 0;
}

  

你可能感兴趣的:(bzoj4400: tjoi2012 桥)