Tarjan 入门题单参考代码

Tarjan 入门

Tarjan 入门题单参考代码

B3609:

#include<bits/stdc++.h>
using namespace std;
struct node{
	int u,v,nxt;
}e[300005];
int n,m;
int dfn[100005];
int cnt,head[100005],low[100005],idx;
void add(int u,int v){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
	return;
}
stack<int>st;
vector<int>g[100005];
vector<int>c;
bool ins[100005];
int tot,bel[100005];
void dfs(int now){
	dfn[now]=++idx;
	low[now]=idx;
	ins[now]=true;
	st.push(now);
	for(int i=head[now];i;i=e[i].nxt){
		int v=e[i].v;
		if(!dfn[v]){
			dfs(v);
			low[now]=min(low[now],low[v]); 
		}
		else if(ins[v])low[now]=min(low[now],dfn[v]);
	}
	if(dfn[now]==low[now]){
		c.clear();
		++tot;
		while(1){
			int v=st.top();
			st.pop();
			c.push_back(v);
			ins[v]=false;
			bel[v]=tot;
			if(v==now)break;
		}
		sort(c.begin(),c.end());
		for(int i=0;i<c.size();i++){
			g[c[0]].push_back(c[i]);
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		add(u,v);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i])dfs(i);
	}
	printf("%d\n",tot);
	for(int i=1;i<=n;i++){
		for(int j=0;j<g[i].size();j++){
			printf("%d ",g[i][j]);
		}
		if(g[i].size()!=0)printf("\n");
	}
	return 0;
}

P2863:

#include<bits/stdc++.h>
using namespace std;
struct node{
	int u,v,nxt;
}e[300005];
int n,m,ans;
int dfn[100005];
int cnt,head[100005],low[100005],idx;
void add(int u,int v){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
	return;
}
stack<int>st;
vector<int>g[100005];
vector<int>c;
bool ins[100005];
int tot,bel[100005];
void dfs(int now){
	dfn[now]=++idx;
	low[now]=idx;
	ins[now]=true;
	st.push(now);
	for(int i=head[now];i;i=e[i].nxt){
		int v=e[i].v;
		if(!dfn[v]){
			dfs(v);
			low[now]=min(low[now],low[v]); 
		}
		else if(ins[v])low[now]=min(low[now],dfn[v]);
	}
	if(dfn[now]==low[now]){
		c.clear();
		++tot;
		while(1){
			int v=st.top();
			st.pop();
			c.push_back(v);
			ins[v]=false;
			bel[v]=tot;
			if(v==now)break;
		}
		sort(c.begin(),c.end());
		for(int i=0;i<c.size();i++){
			g[c[0]].push_back(c[i]);
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		add(u,v);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i])dfs(i);
	}
	for(int i=1;i<=n;i++){
		if(g[i].size()>=2)ans++;
	}
	printf("%d\n",ans);
	return 0;
}

P1726:

#include<bits/stdc++.h>
using namespace std;
struct node{
	int u,v,nxt;
}e[300005];
int n,m;
int dfn[100005];
int cnt,head[100005],low[100005],idx;
void add(int u,int v){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
	return;
}
stack<int>st;
vector<int>g[100005];
vector<int>c;
bool ins[100005];
int tot,bel[100005];
void dfs(int now){
	dfn[now]=++idx;
	low[now]=idx;
	ins[now]=true;
	st.push(now);
	for(int i=head[now];i;i=e[i].nxt){
		int v=e[i].v;
		if(!dfn[v]){
			dfs(v);
			low[now]=min(low[now],low[v]); 
		}
		else if(ins[v])low[now]=min(low[now],dfn[v]);
	}
	if(dfn[now]==low[now]){
		c.clear();
		++tot;
		while(1){
			int v=st.top();
			st.pop();
			c.push_back(v);
			ins[v]=false;
			bel[v]=tot;
			if(v==now)break;
		}
		sort(c.begin(),c.end());
		for(int i=0;i<c.size();i++){
			g[c[0]].push_back(c[i]);
		}
	}
}
vector<int>ans;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v,opt;i<=m;i++){
		scanf("%d%d%d",&u,&v,&opt);
		add(u,v);
        if(opt==2)add(v,u);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i])dfs(i);
	}
    int maxx=0;
	for(int i=1;i<=n;i++){
        if(g[i].size()>maxx){
            maxx=g[i].size();
            ans.clear();
            for(auto j:g[i])ans.push_back(j);
        }
        else {
            if(g[i].size()==maxx){
                bool f=0;
                for(int j=0;j<g[j].size();j++){
                    if(g[i][j]>ans[j]){
                        f=0;
                        break;
                    }
                    if(g[i][j]<ans[j]){
                        f=1;
                        break;
                    }
                }
                if(f){
                    ans.clear();
                    for(auto j:g[i])ans.push_back(j);
                }
            }
        }
	}
    printf("%d\n",maxx);
    for(auto i:ans)printf("%d ",i);
	return 0;
}

P1407:

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=4005;
const int M=20005;
map<string,int>mp;
struct node {
	int u,v,nxt;
} e[M+N];
int cnt,head[N*2];
void add(int u,int v) {
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
stack<int>st;
int dfn[N*2],low[N*2],ins,bel[N*2],tot;
bool cun[N*2];
void dfs(int now) {
	dfn[now]=++ins;
	low[now]=ins;
	cun[now]=1;
	st.push(now);
	int u=now;
	for(int i=head[now],v; i; i=e[i].nxt) {
		v=e[i].v;
		if(!dfn[v]) {
			dfs(v);
			low[u]=min(low[u],low[v]);
		} else if(cun[v])low[u]=min(low[u],dfn[v]);
	}
	if(low[now]==dfn[now]) {
		tot++;
		for(int v; 1;) {
			v=st.top();
			st.pop();
			bel[v]=tot;
			cun[v]=0;
			if(v==now)break;
		}
	}
}
string s;
int u[N],v[N];
int main() {
	scanf("%d",&n);
	for(int i=1; i<=n; i++) {
		cin>>s;
		mp[s]=i*2-1;
		u[i]=mp[s];
		cin>>s;
		mp[s]=i*2;
		v[i]=mp[s];//字符串转为数字,方便存储
		add(u[i],v[i]);//男->女建边
	}
	scanf("%d",&m);
	for(int i=1,uu,vv; i<=m; i++) {
		cin>>s;
		vv=mp[s];
		cin>>s;
		uu=mp[s];
		add(uu,vv);//女->男建边
	}
	for(int i=1; i<=n*2; ++i) {
		if(!dfn[i])dfs(i);
	}
	for(int i=1;i<=n;i++){
		if(bel[u[i]]==bel[v[i]]){
			printf("Unsafe\n");
		}
		else printf("Safe\n");
	}
	return 0;
}

P3387:

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=10005;
const int M=100005;
struct node{
	int u,v,nxt,w;
}e[M],e2[M];
int cnt,cnt2,head[N],a[N],head2[N];
void add(int u,int v){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
stack<int>st;
int dfn[N],low[N],idx,bel[N],sum[N];
bool cun[N];
vector<int>c;
vector<int>g[N];
void dfs(int now){//求出强连通分量,然后把所有在一个强连通分量里的点缩成一个点
	int u=now;
	st.push(now);
	dfn[now]=++idx;
	low[now]=idx;
	cun[now]=1;
	for(int i=head[now],v;i;i=e[i].nxt){
		v=e[i].v;
		if(!dfn[v]){
			dfs(v);
			low[u]=min(low[u],low[v]);
		}
		else if(cun[v])low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[now]){
		c.clear();
		for(int v;1;){
			v=st.top();
			st.pop();
			c.push_back(v);
			cun[v]=0;
			if(v==now)break;
		}
		sort(c.begin(),c.end());
		for(int i=0;i<c.size();i++){
			g[c[0]].push_back(c[i]);
			bel[c[i]]=c[0];
			sum[c[0]]+=a[c[i]];
		}
	}
}
void add2(int u,int v,int w){
	e2[++cnt2].u=u;
	e2[cnt2].v=v;
	e2[cnt2].w=w;
	e2[cnt2].nxt=head2[u];
	head2[u]=cnt2;
}
queue<int>q;
int rd[N],cd[N],dp[N];
void topo(){
	for(int i=1;i<=n;i++){
		if(bel[i]!=i)continue;
		if(rd[i]==0){
			q.push(i);
			dp[i]=sum[i];
		}
	}
	for(int u;!q.empty();){
		u=q.front();
		q.pop();
		for(int i=head2[u],v;i;i=e2[i].nxt){
			v=e2[i].v;
			dp[v]=max(dp[v],dp[u]+e2[i].w);
			rd[v]--;
			if(rd[v]==0)q.push(v);
		}
	}
}
int ans=0;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		add(u,v);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i])dfs(i); 
	} 
	for(int i=1;i<=n;i++){
		if(bel[i]!=i)continue;
	}
	for(int i=1,u,v;i<=cnt;i++){//重新建边
		u=bel[e[i].u];
		v=bel[e[i].v];
		if(u!=v){//细节!两个端点不能在同一强连通分量。
			add2(u,v,sum[v]);
			cd[u]++;
			rd[v]++;
		}
	}
	topo();//拓扑排序 DP
	for(int i=1;i<=n;i++){
		if(bel[i]!=i)continue;
		ans=max(ans,dp[i]);
	}
	printf("%d",ans);
	return 0;
}
/*
一组样例:
4 3
1 1 1 1
1 2
3 4
4 2

ans:3
*/

P2341:

#include<bits/stdc++.h>
using namespace std;
struct node{
	int u,v,nxt;
}e[300005];
int n,m;
int dfn[100005];
int cnt,head[100005],low[100005],idx;
void add(int u,int v){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
	return;
}
stack<int>st;
vector<int>g[100005];
vector<int>c;
bool ins[100005];
int tot,bel[100005];
void dfs(int now){
	dfn[now]=++idx;
	low[now]=idx;
	ins[now]=true;
	st.push(now);
	for(int i=head[now];i;i=e[i].nxt){
		int v=e[i].v;
		if(!dfn[v]){
			dfs(v);
			low[now]=min(low[now],low[v]); 
		}
		else if(ins[v])low[now]=min(low[now],dfn[v]);
	}
	if(dfn[now]==low[now]){
		c.clear();
		while(1){
			int v=st.top();
			st.pop();
			c.push_back(v);
			ins[v]=false;
			if(v==now)break;
		}
		sort(c.begin(),c.end());
		for(int i=0;i<c.size();i++){
			g[c[0]].push_back(c[i]);
			bel[c[i]]=c[0];
		}
	}
}
int du[100005];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		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(bel[i]!=bel[e[j].v]){
				du[bel[i]]++;
			}
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		if(bel[i]!=i)continue;
		if(du[i]==0){//出度为 0 才是受欢迎的牛
			if(ans!=0){	
           /*
           有多个出度为 0 的点说明 DAG 不连通,自然没有受欢迎的牛
				printf("0");
				return 0;
			}
			ans=g[i].size();
		}
	}
	printf("%d",ans);
	return 0;
}

SP14887:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1000005;
struct node{
	int u,v,nxt;
}e[N];
int val[N],cnt,head[N],a[N];
void add(int u,int v){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
struct node2{
	int u,v,nxt;
	ll w;
}e2[N];
int cnt2,head2[N];
void add2(int u,int v,ll w){
	e2[++cnt2].u=u;
	e2[cnt2].v=v;
	e2[cnt2].w=w;
	e2[cnt2].nxt=head2[u];
	head2[u]=cnt2;
}
stack<int>st;
vector<int>g[N];
vector<int>c;
int dfn[N],low[N],idx,bel[N];
ll sum[N];
bool cun[N];
void dfs(int now){//Tarjan
	int u=now;
	st.push(now);
	dfn[now]=++idx;
	low[now]=idx;
	cun[now]=1;
	for(int i=head[now],v;i;i=e[i].nxt){
		v=e[i].v;
		if(!dfn[v]){
			dfs(v);
			low[u]=min(low[u],low[v]);
		}
		else if(cun[v])low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[now]){
		c.clear();
		for(int v;1;){
			v=st.top();
			st.pop();
			c.push_back(v);
			cun[v]=0;
			if(v==now)break; 
		}
		sort(c.begin(),c.end());
		for(int i=0;i<c.size();i++){
			g[c[0]].push_back(c[i]);
			bel[c[i]]=c[0];
			sum[c[0]]+=a[c[i]];
		}
	}
}
int n,m,s,t;
ll dis[N];
int vis[N];
struct pt{
	int pos;
	ll dis;
	friend bool operator <(pt _,pt __){
		return _.dis<__.dis;
	}
};
priority_queue<pt>q;
pt make_node(int pos,ll dis){
	pt new_node;
	new_node.pos=pos;
	new_node.dis=dis;
	return new_node;
} 
void dj(){//dijstkra
	dis[s]=0;
	q.push(make_node(s,dis[s]));
	while(!q.empty()){
		pt p=q.top();
		q.pop();
		int now=p.pos;
		if(vis[now])continue;
		vis[now]=1;
		for(int i=head2[now],v;i;i=e2[i].nxt){
			v=e2[i].v;	
			if(dis[v]<dis[now]+e2[i].w){
				dis[v]=dis[now]+e2[i].w;
				if(!vis[v])q.push(make_node(v,dis[v])); 
			}
		}
	}
}
int main(){
	scanf("%d%d%d%d",&n,&m,&s,&t);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		add(u,v);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i])dfs(i);
	}
	s=bel[s];
	memset(dis,-0x3f3f3f3f3f3f3f3f,sizeof dis);
	for(int i=1,u,v;i<=cnt;i++){
		u=bel[e[i].u];
		v=bel[e[i].v];
		if(u!=v){
			add2(u,v,sum[v]);
		}
	}
	dj();
	printf("%lld",dis[bel[t]]+sum[s]);
	return 0;
}

P1073:

#include<bits/stdc++.h>
using namespace std;
const int N=500005;
//第一张图建图 
struct node{
	int u,v,nxt;
}e[N<<1],e2[N<<1];
int head[N],cnt,n,m;
void add(int u,int v){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
//tarjan
int dfn[N],low[N],idx,cun[N];
vector<int>g[N];
stack<int>st;
vector<int>c;
int a[N];
int bel[N],maxx[N],minn[N];
void dfs(int now){
	low[now]=++idx;
	dfn[now]=idx;
	cun[now]=1;
	st.push(now);
	int u=now;
	for(int i=head[now],v;i;i=e[i].nxt){
		v=e[i].v;
		if(!dfn[v]){
			dfs(v);
			low[u]=min(low[u],low[v]);
		}
		else if(cun[v])low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[now]){
		c.clear();
		int v;
		for(;1;){
			v=st.top();
			st.pop();
			cun[v]=0;
			c.push_back(v);
			if(v==now)break;
		}
		sort(c.begin(),c.end());
		minn[c[0]]=0x3f3f3f3f;
		for(int i=0;i<c.size();i++){
			g[c[0]].push_back(c[i]);
			bel[c[i]]=c[0];
			maxx[c[0]]=max(maxx[c[0]],a[c[i]]);
			minn[c[0]]=min(minn[c[0]],a[c[i]]);
		} 
	} 
}
//第二张图建图
int head2[N],cnt2;
void add2(int u,int v){
	e2[++cnt2].u=u;
	e2[cnt2].v=v;
	e2[cnt2].nxt=head2[u];
	head2[u]=cnt2;
}
//toposort
queue<int>q;
int dp[N],rd[N];
void DP(int s){
	q.push(s);
	dp[s]=max(dp[s],maxx[s]-minn[s]);
	for(int u;!q.empty();){
		u=q.front();
		q.pop();
		for(int i=head2[u],v;i;i=e2[i].nxt){
			v=e2[i].v;
			minn[v]=min(minn[v],minn[u]);
			rd[v]--;
			dp[v]=max(max(dp[u],dp[v]),maxx[v]-minn[v]);
//			printf("%d %d %d %d %d\n",v,maxx[v],minn[v],dp[u],dp[v]);
			if(rd[v]==0)q.push(v);
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1,u,v,opt;i<=m;i++){
		scanf("%d%d%d",&u,&v,&opt);
		if(opt==1)add(u,v);
		else {
			add(u,v);
			add(v,u);
		}
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i])dfs(i);
	}
  //  for(int i=1;i<=n;i++){
 //       for(auto j:g[i])printf("%d ",j);
 //       printf("\n");
 //   }
	for(int i=1,v,u;i<=cnt;i++){
		u=bel[e[i].u];
		v=bel[e[i].v];
		if(u==v)continue;
		add2(u,v);
		rd[v]++;
	}
	DP(bel[1]);
	printf("%d\n",dp[bel[n]]);
	return 0;
}
/*
6 6

100 64 47 50 57 1

1 2 1

2 3 1

1 3 1

1 4 1

1 5 1

5 6 1
*/

P2272:

#include<bits/stdc++.h>
using namespace std;
int n,m;
struct node {
	int u,v,nxt;
} e[1000005],e2[1000005];
int cnt,head[100005],head2[100005];
bool vis[100005];
void add(int u,int v) {
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
	return;
}
void add2(int u,int v) {
	e2[++cnt].u=u;
	e2[cnt].v=v;
	e2[cnt].nxt=head2[u];
	head2[u]=cnt;
	return;
}
int dfn[100005],low[100005];
bool ins[100005];
int tot,idx,bel[100005];
vector<int>c;
vector<int>g[100005];
stack<int>st;
void dfs(int now) {
	dfn[now]=++idx;
	low[now]=idx;
	ins[now]=true;
	st.push(now);
	for(int i=head[now]; i; i=e[i].nxt) {
		int v=e[i].v;
		if(!dfn[v]) {
			dfs(v);
			low[now]=min(low[now],low[v]);
		} else if(ins[v])low[now]=min(low[now],dfn[v]);
	}
	if(dfn[now]==low[now]) {
		c.clear();
		while(1) {
			int v=st.top();
			st.pop();
			c.push_back(v);
			ins[v]=false;
			if(v==now)break;
		}
		sort(c.begin(),c.end());
		for(int i=0; i<c.size(); i++) {
			g[c[0]].push_back(c[i]);
			bel[c[i]]=c[0];
		}
	}
}
long long dp[100005],way[100005],rd[100005],cd[100005],p;
queue<int>q;
void topo() {
	for(int i=1; i<=n; i++) {
		if(rd[i]==0&&g[i].size()) {
			q.push(i);
			dp[i]=g[i].size();
			way[i]=1;
		}
	}
	for(int now; !q.empty();) {
		now=q.front();
		q.pop();
		for(int i=head2[now],v; i; i=e2[i].nxt) {
			v=e2[i].v;
			if(dp[now]+g[v].size()>dp[v]) {
				dp[v]=g[v].size()+dp[now];
				way[v]=way[now];
			} else if(dp[now]+g[v].size()==dp[v]) {
				way[v]=(way[now]+way[v])%p;
			}
			rd[v]--;
			if(rd[v]==0)q.push(v);
		}
	}
}
long long ans1,ans2;
int main() {
	scanf("%d%d%d",&n,&m,&p);
	for(int i=1,u,v; i<=m; i++) {
		scanf("%d%d",&u,&v);
		add(u,v);
	}
	for(int i=1; i<=n; i++) {
		if(!dfn[i])dfs(i);
	}
	cnt=0;
	for(int k=1; k<=n; k++) {
		if(g[k].size()==0)continue;
		memset(vis,0,sizeof(vis));
		for(int i=0; i<g[k].size(); i++) {
			for(int j=head[g[k][i]]; j; j=e[j].nxt) {
				if(k!=bel[e[j].v]&&!vis[bel[e[j].v]]) {//去重
					add2(k,bel[e[j].v]);
					vis[bel[e[j].v]]=1;
				}
			}
		}
	}
	for(int i=1; i<=cnt; i++) {
		rd[e2[i].v]++;
		cd[e2[i].u]++;
	}
	topo();//缩点跑 DP
	for(int i=1; i<=n; i++) {
		if(cd[i]==0) {
			if(dp[i]>ans1) {
				ans1=dp[i];
				ans2=way[i]%p;
			} else if(dp[i]==ans1) {
				ans2=(ans2+way[i])%p;
			}
		}
	}
	printf("%d\n%d",ans1,ans2%p);
	return 0;
}

P3627:

#include<bits/stdc++.h>
using namespace std;
int n,m;
struct node {
	int u,v,nxt,w;
} e[500005],e2[500005];
int cnt,head[500005],head2[500005];
bool vis[500005];
int a[500005];
void add(int u,int v) {
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
	return;
}
void add2(int u,int v,int w) {
	e2[++cnt].u=u;
	e2[cnt].v=v;
	e2[cnt].w=w;
	e2[cnt].nxt=head2[u];
	head2[u]=cnt;
	return;
}
int dfn[500005],low[500005];
bool ins[500005];
int tot,idx,bel[500005],sum[500005];
vector<int>c;
vector<int>g[500005];
stack<int>st;
void dfs(int now) {
	dfn[now]=++idx;
	low[now]=idx;
	ins[now]=true;
	st.push(now);
	for(int i=head[now]; i; i=e[i].nxt) {
		int v=e[i].v;
		if(!dfn[v]) {
			dfs(v);
			low[now]=min(low[now],low[v]);
		} else if(ins[v])low[now]=min(low[now],dfn[v]);
	}
	if(dfn[now]==low[now]) {
		c.clear();
		while(1) {
			int v=st.top();
			st.pop();
			c.push_back(v);
			ins[v]=false;
			if(v==now)break;
		}
		sort(c.begin(),c.end());
		for(int i=0; i<c.size(); i++) {
			g[c[0]].push_back(c[i]);
			bel[c[i]]=c[0];
		}
	}
}
bool viss[500005];
int dis[500005];
int p,bar[500005];
queue<int>q;
void spfa(int s) {
	for(int i=1; i<=n; i++)dis[i]=0;
	q.push(s);
	vis[s]=1;
	dis[s]=sum[s];
	while(!q.empty()) {
		int h=q.front();
		q.pop();
		vis[h]=false;
		for(int i=head2[h]; i; i=e2[i].nxt) {
			int t=e2[i].v;
			if(dis[t]<dis[h]+e2[i].w) {
				dis[t]=dis[h]+e2[i].w;
				if(!vis[t]) {
					q.push(t);
					vis[t]=1;
				}
			}
		}
	}
}
long long ans1;
int s;
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1,u,v; i<=m; i++) {
		scanf("%d%d",&u,&v);
		add(u,v);
	}
	for(int i=1; i<=n; i++) {
		if(!dfn[i])dfs(i);
	}
	cnt=0;
	for(int i=1; i<=n; i++) {
		scanf("%d",&a[i]);
		sum[bel[i]]+=a[i];
	}
	scanf("%d%d",&s,&p);
	for(int i=1; i<=p; i++) {
		scanf("%d",&bar[i]);
	}
	for(int k=1; k<=n; k++) {
		if(g[k].size()==0)continue;
		for(int i=0; i<g[k].size(); i++) {
			for(int j=head[g[k][i]]; j; j=e[j].nxt) {
				if(k!=bel[e[j].v]) {//因为不用统计方案,所以不用去重
					add2(k,bel[e[j].v],sum[bel[e[j].v]]);
				}
			}
		}
	}
	spfa(bel[s]);//与 P2272 不同的是起点是 s 在的强连通分量
	for(int i=1; i<=p; i++) {
		if(dis[bel[bar[i]]]>ans1) {
			ans1=dis[bel[bar[i]]];//终点是有酒吧的点
		}
	}
	printf("%d",ans1);
	return 0;
}

P8436:

#include<bits/stdc++.h>
using namespace std;
const int N=500005;
const int M=2000005;
int n,m;
struct node{
	int u,v,id,nxt;
}e[M*2];
int cnt,head[N];
void add(int u,int v,int id){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].id=id;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
int dfn[N],low[N],idx;
vector<int>c;
vector<int>g[N];
stack<int>st;
int tot;
void dfs(int now,int f){
	dfn[now]=++idx;
	low[now]=idx;
	st.push(now);
	for(int i=head[now];i;i=e[i].nxt){
		if(!dfn[e[i].v]){
			dfs(e[i].v,e[i].id);
			low[now]=min(low[now],low[e[i].v]);
		}
		else{
			if(e[i].id!=f)low[now]=min(low[now],dfn[e[i].v]);//不能走来时的边
//在缩点时我们使用了是否存活的 ins 判断。这里没有 ins,使用这个判断。
		}
	}
	if(low[now]==dfn[now]){
		c.clear();
		tot++;
		while(!st.empty()){
			int v=st.top();
			st.pop();
			c.push_back(v);
			if(v==now)break;
		}
		sort(c.begin(),c.end());
		for(int i=0;i<c.size();++i){
			g[c[0]].push_back(c[i]);
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		add(u,v,i);
		add(v,u,i);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i])dfs(i,-1);
	}
	printf("%d\n",tot); 
	for(int i=1;i<=n;i++){
		if(g[i].size()!=0)printf("%d ",g[i].size());
		for(int j=0;j<g[i].size();j++){
			printf("%d ",g[i][j]);
		}
		if(g[i].size()!=0)printf("\n");
	}
	return 0;
}

P2860:

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=5005,M=10005;
struct node {
	int u,v,id,nxt;
} e[M];
int cnt,head[N];
void add(int u,int v,int id){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].id=id;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
int dfn[N],low[N],idx,bel[N],tot;
stack<int>st;
vector<int>c;
vector<int>g[N]; 
void dfs(int now,int f){
	dfn[now]=++idx;
	low[now]=idx;
	st.push(now);
	for(int i=head[now];i;i=e[i].nxt){
		if(!dfn[e[i].v]){
			dfs(e[i].v,e[i].id);
			low[now]=min(low[now],low[e[i].v]);
		}
		else{
			if(e[i].id!=f)low[now]=min(low[now],dfn[e[i].v]);
		}
	}
	if(low[now]==dfn[now]){
		c.clear();
		tot++;
		while(!st.empty()){
			int v=st.top();
			st.pop();
			c.push_back(v);
			if(v==now)break;
		}
		sort(c.begin(),c.end());
		for(int i=0;i<c.size();++i){
			g[c[0]].push_back(c[i]);
			bel[c[i]]=c[0];
		}
	}
}
int du[N],sum;
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1,u,v; i<=m; i++) {
		scanf("%d%d",&u,&v);
		add(u,v,i);
		add(v,u,i);
	}
	dfs(1,-1);
	for(int i=1,u,v;i<=cnt;i+=2){
		u=bel[e[i].u];
		v=bel[e[i].v];
		if(u==v)continue;
		du[u]++;
		du[v]++;
	}
	for(int i=1;i<=n;i++){
		if(du[i]==1)sum++;
	}
	printf("%d",(sum+1)/2);
	return 0;
}
/*
这个题思路比较复杂。

首先对于一棵树,设叶子节点数量为 k,则一定可以在 (k+1)/2 条边完成任务。

于是缩边双,变成一棵树,然后就可以做了。

关于边双缩完后为什么会成为树:边双缩完后,所有边都是割边,自然是树。
*/

P8435:

#include<bits/stdc++.h>
using namespace std;
const int N=500005;
//建图
struct node{
	int u,v,nxt;
}e[N<<3];
int head[N],cnt;
void add(int u,int v){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
} 
int n,m;
vector<int>g[N];
int dfn[N],low[N],idx,rt,tot;
stack<int>st;
void dfs(int now,int fa){
	int u=now,son=0;
	low[u]=++idx;
	dfn[u]=idx;
	st.push(now);
	for(int i=head[now],v;i;i=e[i].nxt){
		v=e[i].v;
		if(!dfn[v]){
			son++;
			dfs(v,now);
			low[u]=min(low[u],low[v]);
			if(dfn[u]<=low[v]){
				tot++;
				while(!st.empty()){
					g[tot].push_back(st.top());
					if(st.top()==v){
						st.pop();
						break;
					}
					st.pop();
				}
				g[tot].push_back(u);
			}
		}
		else if(v!=fa)low[u]=min(low[u],dfn[v]);
	}
	if(fa==0&&son==0){
		g[++tot].push_back(u);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i]){
			rt=i;
			while(!st.empty())st.pop();
			dfs(i,0);
		}
	}
	printf("%d\n",tot);
	for(int i=1;i<=tot;i++){
		printf("%d ",g[i].size());
		for(auto j:g[i])printf("%d ",j);
		printf("\n");
	}
	return 0;
}

B3610:

#include<bits/stdc++.h>
using namespace std;
const int N=500005;
//建图
struct node{
	int u,v,nxt;
}e[N<<3];
int head[N],cnt;
void add(int u,int v){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
} 
int n,m;
vector<int>g[N];
int dfn[N],low[N],idx,rt,tot;
stack<int>st;
void dfs(int now,int fa){
	int u=now,son=0;
	low[u]=++idx;
	dfn[u]=idx;
	st.push(now);
	for(int i=head[now],v;i;i=e[i].nxt){
		v=e[i].v;
		if(!dfn[v]){
			son++;
			dfs(v,now);
			low[u]=min(low[u],low[v]);
			if(dfn[u]<=low[v]){
				tot++;
				while(!st.empty()){
					g[tot].push_back(st.top());
					if(st.top()==v){
						st.pop();
						break;
					}
					st.pop();
				}
				g[tot].push_back(u);
			}
		}
		else if(v!=fa)low[u]=min(low[u],dfn[v]);
	}
//	if(fa==0&&son==0){
//		g[++tot].push_back(u);
//	}
}
bool cmp(vector<int> _,vector<int> __){
	int len=min(_.size(),__.size());
	for(int i=0;i<len;i++){
		if(_[i]<__[i])return 1;
		else if(_[i]>__[i])return 0;
	}
	return _.size()<__.size();
} 
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i]){
			rt=i;
			while(!st.empty())st.pop();
			dfs(i,0);
		}
	}
	printf("%d\n",tot);
	for(int i=1;i<=tot;i++)sort(g[i].begin(),g[i].end());
	sort(g+1,g+tot+1,cmp);
	for(int i=1;i<=tot;i++){
		for(auto j:g[i])printf("%d ",j);
		printf("\n");
	}
	return 0;
}

P3388:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int x=0,y=1;
	char c=getchar();
	while(c>'9'||c<'0'){
		if(c=='-')y=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*y;
}
const int N=20005;
int n,m;
int rd[N],nxt[N*10],cnt,dfn[N],root=0,fl[N],low[N],num=0,head[N],to[N*10];
void add(int u,int v) {
	cnt++;
	rd[v]++;
	nxt[cnt]=head[u];
	head[u]=cnt;
	to[cnt]=v;
	return;
}
int ans=0;
void tarjan(int u,int fa){
	low[u]=dfn[u]=++num;
	int sum=0;
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i];
		if(v==fa)continue;
		if(!dfn[v]){
			tarjan(v,u);
			if(low[v]>=dfn[u]){
				sum++;
			}//>求割边 
			low[u]=min(low[u],low[v]);
		}
		else low[u]=min(low[u],dfn/*求割边改成low*/[v]);   
	}
	if(u==root)sum--;
	if(sum>0)fl[u]=1,ans++;
	return;
}
int main() {
	n=read();
	m=read();
	for(int i=1; i<=m; i++) {
		int u,v;
		u=read();
		v=read();
		add(u,v);
		add(v,u);
	}
	for(int i=1; i<=n; i++)
		if(!dfn[i]) {
			root=i;
			tarjan(i,0);
		}
	printf("%d\n",ans);
	for(int i=1; i<=n; i++)if(fl[i])printf("%d ",i);
	return 0;
}

UVA315:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int x=0,y=1;
	char c=getchar();
	while(c>'9'||c<'0'){
		if(c=='-')y=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*y;
}
const int N=20005;
int n,m;
int rd[N],nxt[N*10],cnt,dfn[N],root=0,fl[N],low[N],num=0,head[N],to[N*10];
void add(int u,int v) {
	cnt++;
	rd[v]++;
	nxt[cnt]=head[u];
	head[u]=cnt;
	to[cnt]=v;
	return;
}
int ans=0;
void tarjan(int u,int fa){
	low[u]=dfn[u]=++num;
	int sum=0;
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i];
		if(v==fa)continue;
		if(!dfn[v]){
			tarjan(v,u);
			if(low[v]>=dfn[u]){
				sum++;
			}//>求割边 
			low[u]=min(low[u],low[v]);
		}
		else low[u]=min(low[u],dfn/*求割边改成low*/[v]);   
	}
	if(u==root)sum--;
	if(sum>0)fl[u]=1,ans++;
	return;
}
bool solve(){
	char ch;
	cnt=0;
	memset(head,0,sizeof(head));
	memset(dfn,0,sizeof(dfn));
	memset(low,0,sizeof(low));
	memset(fl,0,sizeof(fl));
	memset(rd,0,sizeof(rd));
	memset(nxt,0,sizeof(nxt));
	memset(to,0,sizeof(to));
	num=0;root=0;
	int u,v;
	scanf("%d",&n);
	if(n==0)return false;
	while(1){
		scanf("%d",&u);
		if(u==0)break;
		while(1){
			ch=getchar();
			if(ch=='\n')break;
			scanf("%d",&v);
			add(u,v);
			add(v,u);
		}
	}
	for(int i=1; i<=n; i++)
		if(!dfn[i]) {
			root=i;
			tarjan(i,0);
		}
	int anss=0;
	for(int i=1; i<=n; i++)if(fl[i])anss++;
	printf("%d\n",anss);
	return 1;
}
int main() {
	while(solve());
}

P3469:

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=100005;
const int M=500005;
struct node{
	int u,v,nxt;
}e[M*2];
int cnt,head[N];
void add(int u,int v){
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
bool cut[N];
int dfn[N],low[N],idx;
long long siz[N];
long long ans[N];
void dfs(int now){
	dfn[now]=++idx;
	low[now]=idx;
	siz[now]=1;
	long long sum=0,son=0,flag=0;
	for(int i=head[now],v;i;i=e[i].nxt){
		v=e[i].v;
		if(!dfn[v]){
			dfs(v);
			low[now]=min(low[now],low[v]);
			siz[now]+=siz[v];
			if(low[v]>=dfn[now]){
				ans[now]=(ans[now]+siz[v]*(n-siz[v]));
				sum+=siz[v];
				flag++;
				if(now!=1||flag>1)cut[now]=1;
			}
		}
		else low[now]=min(low[now],dfn[v]);
	}
	if(!cut[now])ans[now]=2*(n-1);//不是割点:2*(n-1) 个。
	else ans[now]=(ans[now]+n-1+(n-sum-1)*(sum+1));
    /*
    是割点:
    割点一定会把图分成若干个连通分量,统计它们的数量然后用乘法原理即可。
    假如一个连通分量里有 k 个点,则有 (n-k)*k 对点对无法到达。
    */
}
signed main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	dfs(1);
	for(int i=1;i<=n;i++){
		printf("%lld\n",ans[i]);
	}
	return 0;
}
posted @   Weslie_qwq  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示