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;
}
分类:
个人记录
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】