1 条题解

  • -2
    @ 2022-8-26 10:20:26
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #include<unordered_map>
    #include<map>
    using namespace std;
    inline int read()
    {
        char c=getchar();int x=0;bool f=0;
        for(;!isdigit(c);c=getchar())f^=!(c^45);
        for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
        if(f)x=-x;return x;
    }
    const int N=3e5+5;
    int n,m,q,k,head[N],cnt,d[N];
    struct Graph
    {
    	int head[N],cnt;
    	struct edge
    	{
    		int to,nxt;
    	}e[N*2];
    	void add(int u,int v)
    	{
    		e[++cnt].to=v;
    		e[cnt].nxt=head[u];
    		head[u]=cnt;
    	}
    }G1,G2;
    struct graph
    {
    	int head[20],cnt;
    	struct edge
    	{
    		int to,nxt,v;
    	}e[30*2];
    	void add(int u,int v,int w)
    	{
    //		cout<<u<<" "<<v<<" "<<w<<endl;
    		e[++cnt].to=v;
    		e[cnt].nxt=head[u];
    		head[u]=cnt;
    		e[cnt].v=w;
    	}
    	void clear()
    	{
    		cnt=0;
    		memset(head,0,sizeof head);
    	}
    }G3,G4;
    struct edge
    {
    	int to,nxt;
    }e[N*2];
    void add(int u,int v)
    {
    	e[++cnt].to=v;
    	e[cnt].nxt=head[u];
    	head[u]=cnt;
    }
    int dfn[N],low[N],v[N],col[N],colw[N],tot,s[N],top,Sum,st,ed,h[15],sum[N],lg[N],f[N][20],dep[N],Tot,L[N],ind[N];
    #define sum Sum
    void dfs(int now)//原图 tarjan 
    {
    	dfn[now]=low[now]=++tot;
    	s[++top]=now;
    	v[now]=1;
    	for(int i=head[now];i;i=e[i].nxt)
    	if(!dfn[e[i].to]) dfs(e[i].to),low[now]=min(low[now],low[e[i].to]);
    	else if(v[e[i].to]) low[now]=min(low[now],dfn[e[i].to]);
    	if(low[now]==dfn[now])
    	{
    		int x;
    		sum++;
    		do
    		{
    			x=s[top--];
    			col[x]=sum;
    			v[x]=0;
    			colw[sum]++;
    		}while(now!=x);
    	}
    }
    void topo()//G1DAG->G2 tree 
    {
    	queue<int> q;
    	for(int i=1;i<=sum;i++)
    	if(!d[i]) q.push(i);
    	while(!q.empty())
    	{
    		int now=q.front();q.pop();
    		for(int i=G1.head[now];i;i=G1.e[i].nxt)
    		{
    			d[G1.e[i].to]--;
    			if(d[G1.e[i].to]==0)
    			{
    				G2.add(now,G1.e[i].to);
    				ind[G1.e[i].to]++;
    			//	cout<<now<<" "<<G1.e[i].to<<endl;
    				q.push(G1.e[i].to);
    			}
    		}
    	}
    }
    #undef sum
    struct Hash
    {
    	unordered_map<int,int> mp;
    	int cnt;
    	void clear()
    	{
    		mp.clear();
    		cnt=0;
    	}
    	int get(int x)
    	{
    		if(mp[x]==0) mp[x]=++cnt;
    		return mp[x];
    	}
    }H;
    void dfs1(int now,int fa)//G2 tree dfs :lca,dfn(L),权值前缀和(sum) 
    {
    	f[now][0]=fa;
    	L[now]=++Tot;
    	dep[now]=dep[fa]+1;
    	for(int i=1;i<=lg[dep[now]];i++)
    	f[now][i]=f[f[now][i-1]][i-1];
    	sum[now]=sum[fa]+colw[now];
    	for(int i=G2.head[now];i;i=G2.e[i].nxt)
    	{
    		if(G2.e[i].to!=fa)
    		dfs1(G2.e[i].to,now);
    	}
    }
    int LCA(int x,int y)
    {
    	if(dep[x]<dep[y]) swap(x,y);
    	while(dep[x]>dep[y]) x=f[x][lg[dep[x]-dep[y]]-1];
    	if(x==y) return x;
    	for(int i=lg[dep[x]];i>=0;i--) 
    	if(f[x][i]!=f[y][i])
    	x=f[x][i],y=f[y][i];
    	return f[x][0];
    }
    bool cmp(int x,int y)
    {
    	return L[x]<L[y];
    }
    int vis[30],vis2[30],vp[30],val[30];
    int work()
    {
    	memset(vis,0,sizeof vis);
    	memset(vp,0,sizeof vp);
    	queue<int> q;
    //	cout<<H.get(st)<<" "<<H.get(ed)<<endl;
    	q.push(H.get(st));
    	while(!q.empty())//G3 bfs
    	{
    		int now=q.front();q.pop();
    		vp[now]=1;
    		for(int i=G3.head[now];i;i=G3.e[i].nxt)
    		{
    			if(!vis[i])
    			{
    				vis[i]=1;
    				q.push(G3.e[i].to);
    			}
    		}
    	}
    	int ans=0;
    	memset(vis2,0,sizeof vis2);
    	q.push(H.get(ed));
    	while(!q.empty())//G4 bfs
    	{
    		int now=q.front();q.pop();
    		if(vp[now]) ans+=val[now],vp[now]=0;
    		for(int i=G4.head[now];i;i=G4.e[i].nxt)
    		{
    			if(!vis2[i])
    			{
    				vis2[i]=1;
    				if(vis[i]) ans+=G4.e[i].v,vis[i]=0; 
    				q.push(G4.e[i].to);
    			}
    		}
    	}
    	memset(val,0,sizeof val);
    	return ans;
    }
    int main()
    {
    	n=read();m=read();q=read();k=read();
    	for(int i=1;i<=n;i++)
    	lg[i]=lg[i/2]+1;
    	for(int i=1;i<=m;i++)
    	{
    		int u=read(),v=read();
    		add(u,v);
    	}
    	for(int i=1;i<=n;i++)
    	if(!dfn[i]) dfs(i);
    	for(int i=1;i<=n;i++)
    	for(int j=head[i];j;j=e[j].nxt)
    	if(col[i]!=col[e[j].to])
    	G1.add(col[i],col[e[j].to]),d[col[e[j].to]]++;
    	topo();
    	int root=0;
    	for(int i=1;i<=Sum;i++)
    	if(ind[i]==0) root=i;
    	dfs1(root,0);
    	for(int i=1;i<=q;i++)
    	{
    		G3.clear();G4.clear();H.clear();
    		st=read();ed=read();
    		st=col[st];ed=col[ed];
    		h[1]=st;h[2]=ed;
    		top=0;
    		for(int j=1;j<=k;j++)
    		{
    			int u=read(),v=read();
    			u=col[u];v=col[v];
    			if(u==v) continue;
    			G3.add(H.get(u),H.get(v),0);
    			G4.add(H.get(v),H.get(u),0);
    			h[j*2+1]=u;h[j*2+2]=v;
    		}
    		sort(h+1,h+(k+1)*2+1,cmp);
    		int qwq=unique(h+1,h+(k+1)*2+1)-h-1;
    		for(int j=1;j<=qwq;j++)
    		val[H.get(h[j])]=colw[h[j]];
    		s[++top]=h[1];
    		for(int j=2;j<=qwq;j++)
    		{
    			int lca=LCA(h[j],s[top]);
    			val[H.get(lca)]=colw[lca];
    			while(1)
    			{
    				if(dep[lca]>=dep[s[top-1]])
    				{
    					if(lca!=s[top])
    					{
    						G3.add(H.get(lca),H.get(s[top]),sum[f[s[top]][0]]-sum[lca]);
    						G4.add(H.get(s[top]),H.get(lca),sum[f[s[top]][0]]-sum[lca]);
    						if(lca!=s[top-1])
    						s[top]=lca;
    						else top--;
    					}
    					break;
    				}
    				else
    				{
    					G3.add(H.get(s[top-1]),H.get(s[top]),sum[f[s[top]][0]]-sum[s[top-1]]);
    					G4.add(H.get(s[top]),H.get(s[top-1]),sum[f[s[top]][0]]-sum[s[top-1]]);
    					top--;
    				}
    			}
    			s[++top]=h[j];
    		}
    		while(top-1)
    		{
    	//		cout<<"qwq";
    			G3.add(H.get(s[top-1]),H.get(s[top]),sum[f[s[top]][0]]-sum[s[top-1]]);
    			G4.add(H.get(s[top]),H.get(s[top-1]),sum[f[s[top]][0]]-sum[s[top-1]]);
    			top--;
    		}
    		printf("%d\n",work());
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    135
    时间
    1000ms
    内存
    1024MiB
    难度
    10
    标签
    递交数
    22
    已通过
    0
    上传者