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; }