萌新样例没过求条
查看原帖
萌新样例没过求条
539133
q1uple楼主2024/10/18 21:56

好像是虚树那一部分的问题

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e6+5,mod=1e9+7,INF=2e9;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
#define qmi(a,b) a=min(a,b)
#define qma(a,b) a=max(a,b)
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define atrep(i,l,r) for(int i=(r);i>=(l);i--)
#define vec vector<int>
#define pb push_back
namespace fast_IO {
#define IOSIZE 100000
	char ibuf[IOSIZE], obuf[IOSIZE], *p1 = ibuf, *p2 = ibuf, *p3 = obuf;
#define getchar() ((p1==p2)and(p2=(p1=ibuf)+fread(ibuf,1,IOSIZE,stdin),p1==p2)?(EOF):(*p1++))
#define putchar(x) ((p3==obuf+IOSIZE)&&(fwrite(obuf,p3-obuf,1,stdout),p3=obuf),*p3++=x)
#define isdigit(ch) (ch>47&&ch<58)
#define isspace(ch) (ch<33)
	template<typename T> inline T read() { T s = 0; int w = 1; char ch; while (ch = getchar(), !isdigit(ch) and (ch != EOF)) if (ch == '-') w = -1; if (ch == EOF) return false; while (isdigit(ch)) s = s * 10 + ch - 48, ch = getchar(); return s * w; }
	template<typename T> inline bool read(T &s) { s = 0; int w = 1; char ch; while (ch = getchar(), !isdigit(ch) and (ch != EOF)) if (ch == '-') w = -1; if (ch == EOF) return false; while (isdigit(ch)) s = s * 10 + ch - 48, ch = getchar(); return s *= w, true; }
	template<typename T> inline void print(T x) { if (x < 0) putchar('-'), x = -x; if (x > 9) print(x / 10); putchar(x % 10 + 48); }
	inline bool read(char &s) { while (s = getchar(), isspace(s)); return true; }
	inline bool read(char *s) { char ch; while (ch = getchar(), isspace(ch)); if (ch == EOF) return false; while (!isspace(ch)) *s++ = ch, ch = getchar(); *s = '\000'; return true; }
	inline void print(char x) { putchar(x); }
	inline void print(char *x) { while (*x) putchar(*x++); }
	inline void print(const char *x) { for (int i = 0; x[i]; i++) putchar(x[i]); }
	inline bool read(std::string& s) { s = ""; char ch; while (ch = getchar(), isspace(ch)); if (ch == EOF) return false; while (!isspace(ch)) s += ch, ch = getchar(); return true; }
	inline void print(std::string x) { for (int i = 0, n = x.size(); i < n; i++) putchar(x[i]); }
	inline bool read(bool &b) { char ch; while(ch=getchar(), isspace(ch)); b=ch^48; return true; }
	inline void print(bool b) { putchar(b+48); }
	template<typename T, typename... T1> inline int read(T& a, T1&... other) { return read(a) + read(other...); }
	template<typename T, typename... T1> inline void print(T a, T1... other) { print(a), print(other...); }
	struct Fast_IO { ~Fast_IO() { fwrite(obuf, p3 - obuf, 1, stdout); } } io;
	template<typename T> Fast_IO& operator >> (Fast_IO &io, T &b) { return read(b), io; }
	template<typename T> Fast_IO& operator << (Fast_IO &io, T b) { return print(b), io; }
#define cout io
#define cin io
#define endl '\n'
} using namespace fast_IO;
struct node{
	int nxt,v,w;
}g[N*2];
int h[N],idx=0;
int n,m,K,Q;
void add(int a,int b,int c){
	g[++idx].nxt=h[a],g[idx].v=b,g[idx].w=c,h[a]=idx;
}
namespace dijkstra{
	int dis[N],vis[N],len[N],pre[N];
	void dij(){
		fill(dis+1,dis+n+1,INF);
		priority_queue<pii,vector<pii>,greater<pii> >q;
		q.push({0,K});dis[K]=0;
		while(!q.empty()){
			pii o=q.top();q.pop();
			int u=o.second;
			if(vis[u])	continue;
			vis[u]=1;
			for(int i=h[u];i;i=g[i].nxt){
				int v=g[i].v,w=g[i].w;
				if(dis[v]>dis[u]+w){
					dis[v]=dis[u]+w;
					pre[v]=u;
					len[v]=w;
					q.push({dis[v],v});
				}else if(dis[v]==dis[u]+w&&pre[v]>u){
					pre[v]=u;
					len[v]=w;
				}
			}
		}
		memset(h,0,sizeof h);
		idx=0;
		rep(i,1,n){
			if(i!=K){
//				cout<<i<<" "<<pre[i]<<endl;
				add(i,pre[i],len[i]);add(pre[i],i,len[i]);				
			}
		}
	}	
}
namespace Tree{
	int top[N],son[N],fa[N],dep[N],sz[N],dis[N],dfn[N],id[N];
	void dfs(int u,int fath,int depth){
		fa[u]=fath,dep[u]=depth,sz[u]=1;
		for(int i=h[u];i;i=g[i].nxt){
			int v=g[i].v,w=g[i].w;
			if(v==fath)	continue;
			dis[v]=dis[u]+w;
			dfs(v,u,depth+1);
			sz[u]+=sz[v];
			if(sz[son[u]]<sz[v])	son[u]=v;
		}
	}
	int tt=0;
	void dfs(int u,int tf){
		top[u]=tf,dfn[u]=++tt,id[tt]=u;
		if(son[u])	dfs(son[u],tf);
		for(int i=h[u];i;i=g[i].nxt){
			int v=g[i].v;
			if(v==fa[u]||v==son[u])	continue;
			dfs(v,v);
		}
	}
	int LCA(int x,int y){
		while(top[x]!=top[y]){
			if(dep[top[x]]<dep[top[y]])	swap(x,y);
			x=fa[top[x]];
		}
		return dep[x]>dep[y]?y:x;
	}
	int DIS(int x,int y){
		return dis[x]+dis[y]-2*dis[LCA(x,y)];
	}
	void build(){
		dfs(1,0,0);
		dfs(1,1);
	}
}
int val[N],p[N],a[N];
namespace img{
	struct node{
		int nxt,v,w;
	}g[N*2];
	int h[N],idx=0;
	void add(int a,int b,int c){
		g[++idx].nxt=h[a],g[idx].v=b,g[idx].w=c,h[a]=idx;
	}
	bool cmp(int x,int y){
		return Tree::dfn[x]<Tree::dfn[y];
	}
	void build(){
		int k;cin>>k;
		rep(i,1,k)	cin>>p[i];
		k++,p[k]=K;
		sort(p+1,p+k+1,cmp);
		int len=0;
		rep(i,1,k-1){
			a[++len]=p[i];
			a[++len]=Tree::LCA(p[i],p[i+1]);
		}
		a[++len]=p[k];
		a[++len]=1;
		sort(a+1,a+len+1,cmp);
		rep(i,1,len)	h[a[i]]=0;
		len=unique(a+1,a+len+1)-a-1;
		idx=0;		
		rep(i,1,len-1){
			int lc=Tree::LCA(a[i],a[i+1]);int dis=Tree::DIS(lc,a[i+1]);
			add(lc,a[i+1],dis);add(a[i+1],lc,dis);
		}
	}
	int dfs(int u,int fa){
		int res=0;
		for(int i=h[u];i;i=g[i].nxt){
			int v=g[i].v,w=g[i].w;
			if(v==fa)	continue;
			int tmp=dfs(v,u);
			if(val[v])	res+=w;
			else res+=min(tmp,w);
		}
		return res;
	}
}
signed main(){
	cin>>n>>m>>K>>Q;
	rep(i,1,m){
		int a,b,c;
		cin>>a>>b>>c;
		add(a,b,c);add(b,a,c);
	}
	dijkstra::dij();
	Tree::build();
	rep(i,1,Q){
		int opt;cin>>opt;
		if(opt==0){
			int num;cin>>num;
			rep(i,1,num){
				int x;cin>>x;
				val[x]^=1;
			}
		}else{
			img::build();
			int x=img::dfs(1,0);
			if(x==0)	cout<<-1<<endl;
			else cout<<x<<endl;
		}
	}
}
2024/10/18 21:56
加载中...