zoukankan      html  css  js  c++  java
  • 题解 P2416 【泡芙】

    这道题首先需要跑一遍边双连通分量,然后剩下来的就是一颗树,每个点有其点权,询问对于树上一条 ((u,v)) 的简单路径,时候经过的点的点权和不为 (0)

    其他题解基本都是跑 (LCA),去求路径的权值,其实这并没有必要,因为两点间的路径点权和为 (0) 的是一个连通块,若询问的 (2) 点在同一个连通块里就说明它们之间路径的点权和为 (0),求连通块可用并查集做,若想得到完美的 (O(n)) 解,则可以 (bfs)

    并查集

    #include<bits/stdc++.h>
    #define log(a) cerr<<"33[32m[DEBUG] "<<#a<<'='<<(a)<<" @ line "<<__LINE__<<"33[0m"<<endl
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    #define SZ(x) ((int)x.size()-1)
    #define ms(a,b) memset(a,b,sizeof a)
    #define F(i,a,b) for(int i=(a);i<=(b);++i)
    #define DF(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    inline int read(){char ch=getchar(); int w=1,c=0;
    	for(;!isdigit(ch);ch=getchar()) if (ch=='-') w=-1;
    	for(;isdigit(ch);ch=getchar()) c=(c<<1)+(c<<3)+(ch^48);
    	return w*c;
    }
    const int N=3e5+10;
    int n,m,cnt,dfn[N],low[N],sccnum[N],sk[N],tot,scccnt,sccval[N],fa[N];
    vector<pair<int,int> >v[N];
    vector<int>scctree[N];
    void dfs(int x,int fa){
    	low[x]=dfn[x]=++cnt;
    	sk[tot++]=x;
    	for(pair<int,int>i:v[x])
    		if(!dfn[i.fi]){
    			dfs(i.fi,x);
    			low[x]=min(low[x],low[i.fi]);
    		}else if(i.fi!=fa){
    			low[x]=min(low[x],dfn[i.fi]);
    		}
    	if(low[x]==dfn[x]){
    		scccnt++;
    		do{
    			sccnum[sk[--tot]]=scccnt;
    		}while(sk[tot]!=x);
    	}
    }
    inline int find(int x){
    	if(fa[x]==x)return x;
    	return fa[x]=find(fa[x]);
    }
    int main(){
    	n=read(),m=read();
    	F(i,1,m){
    		int x=read(),y=read(),z=read();
    		v[x].pb(mp(y,z));
    		v[y].pb(mp(x,z));
    	}
    	dfs(1,0);
    	F(i,1,n)
    		for(pair<int,int>j:v[i])
    			if(sccnum[i]==sccnum[j.fi])sccval[sccnum[i]]+=j.se;
    			else if(!j.se)scctree[sccnum[i]].pb(sccnum[j.fi]);
    	F(i,1,scccnt)fa[i]=i;
    	F(i,1,scccnt){
    	    int l=find(i);
    		if(!sccval[i])
    			for(int j:scctree[i])
    				if(!sccval[j])
    					fa[find(j)]=l;
    	}
    	int q=read();while(q--){
    		int s=read(),t=read();
    		if(sccval[sccnum[s]]||sccval[sccnum[t]])puts("YES");
    		else if(find(sccnum[s])==find(sccnum[t]))puts("NO");
    			else puts("YES");
    	}
    }
    

    (bfs)

    #include<bits/stdc++.h>
    #define log(a) cerr<<"33[32m[DEBUG] "<<#a<<'='<<(a)<<" @ line "<<__LINE__<<"33[0m"<<endl
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    #define SZ(x) ((int)x.size()-1)
    #define ms(a,b) memset(a,b,sizeof a)
    #define F(i,a,b) for(int i=(a);i<=(b);++i)
    #define DF(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    inline int read(){char ch=getchar(); int w=1,c=0;
    	for(;!isdigit(ch);ch=getchar()) if (ch=='-') w=-1;
    	for(;isdigit(ch);ch=getchar()) c=(c<<1)+(c<<3)+(ch^48);
    	return w*c;
    }
    const int N=3e5+10;
    int n,m,cnt,dfn[N],low[N],sccnum[N],sk[N],tot,scccnt,sccval[N],block[N];
    vector<pair<int,int> >v[N];
    vector<int>scctree[N];
    void dfs(int x,int fa){
    	low[x]=dfn[x]=++cnt;
    	sk[tot++]=x;
    	for(pair<int,int>i:v[x])
    		if(!dfn[i.fi]){
    			dfs(i.fi,x);
    			low[x]=min(low[x],low[i.fi]);
    		}else if(i.fi!=fa){
    			low[x]=min(low[x],dfn[i.fi]);
    		}
    	if(low[x]==dfn[x]){
    		scccnt++;
    		do{
    			sccnum[sk[--tot]]=scccnt;
    		}while(sk[tot]!=x);
    	}
    }
    queue<int>q;
    int main(){
    	n=read(),m=read();
    	F(i,1,m){
    		int x=read(),y=read(),z=read();
    		v[x].pb(mp(y,z));
    		v[y].pb(mp(x,z));
    	}
    	dfs(1,0);
    	F(i,1,n)
    		for(pair<int,int>j:v[i])
    			if(sccnum[i]==sccnum[j.fi])sccval[sccnum[i]]+=j.se;
    			else if(!j.se)scctree[sccnum[i]].pb(sccnum[j.fi]);
    	F(i,1,scccnt)
    		if(!block[i]&&!sccval[i]){
    			block[i]=i;
    			q.push(i);
    			while(q.size()){
    				int x=q.front();q.pop();
    				for(int j:scctree[x])
    					if(!block[j]&&!sccval[j]){
    						block[j]=i;
    						q.push(j);
    					}
    			}
    		}
    	int q=read();while(q--){
    		int s=read(),t=read();
    		if(!block[sccnum[s]]||!block[sccnum[t]])puts("YES");
    		else if(block[sccnum[s]]==block[sccnum[t]])puts("NO");
    			else puts("YES");
    	}
    }
    

    卡常的最优解就不放了

  • 相关阅读:
    在变量中如何插入变量
    perl 模块
    perl中的引用
    数组:pop&清空数组&查找某元素是否在数组内
    整个文件做为一个数组
    checkbox判断选中
    网页存储倒计时与解决网页cookie保存多个相同key问题
    wmframework v2.0 手册(一)系统框架介绍
    r cannot be resolved to a variable android
    锁定Chrome的下载文件夹快捷方式到win7任务栏
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/14818902.html
Copyright © 2011-2022 走看看