强联通:
hdu3861 The King’s Problem
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=50003,M=100003,inf=1e8;
#define M(a) memset(a,0,sizeof(a))
int be[N],dfn[N],low[N],st[N],dis[N],h[N],in[N],n,m,x,y,tot,u,v,s,t,cnt,top,tim,T,i,j,hh[N];
queue<int>q;
struct kk{
int to,ne;
}a[M];
struct node{
int to,ne,w;
}e[M<<4];
void add(int x,int y){
a[++tot]=(kk){y,h[x]};
h[x]=tot;
}
void add2(int x,int y){
e[++tot]=(node){y,hh[x],1};
hh[x]=tot;
e[++tot]=(node){x,hh[y],0};
hh[y]=tot;
}
void tarjan(int u){
low[u]=dfn[u]=++tim;
in[u]=1;
st[top++]=u;
for (int i=h[u];i;i=a[i].ne){
int v=a[i].to;
if (!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]);
else if (in[v]) low[u]=min(low[u],dfn[v]);
}
if (low[u]==dfn[u]){
int x;cnt++;
do{
x=st[--top];
be[x]=cnt;
in[x]=0;
}while (x!=u);
}
}
bool bfs(){
q.push(s);
memset(dis,63,sizeof(dis));
dis[s]=0;
while (!q.empty()){
int u=q.front();q.pop();
for (int i=hh[u];i;i=e[i].ne){
int v=e[i].to;
if (dis[v]>inf && e[i].w) dis[v]=dis[u]+1,q.push(v);
}
}
return dis[t]<inf;
}
int dfs(int u,int lim){
if (u==t || !lim) return lim;
int f,flow=0;
for (int i=hh[u];i;i=e[i].ne){
int v=e[i].to;
if (dis[v]==dis[u]+1 && e[i].w && (f=dfs(v,min(lim,e[i].w)))){
e[i].w-=f;lim-=f;
e[i^1].w+=f;flow+=f;
if (!lim) return flow;
}
}
dis[u]=-1;
return flow;
}
int dinic(){
int ans=0;
while (bfs()) ans+=dfs(s,inf);
return ans;
}
int main(){
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&m);
tim=top=tot=cnt=0;
M(dfn);M(h);M(hh);
for (i=1;i<=m;i++) scanf("%d%d",&x,&y),add(x,y);
for (i=1;i<=n;i++)
if (!dfn[i]) tarjan(i);
tot=1;
for (i=1;i<=n;i++)
for (j=h[i];j;j=a[j].ne){
v=a[j].to;
if (be[i]!=be[v]) add2(be[i],be[v]+cnt);
}
s=cnt<<1|1;t=s+1;
for (i=1;i<=cnt;i++) add2(s,i),add2(i+cnt,t);
printf("%d\n",cnt-dinic());
}
}
hdu3594 Cactus
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define M(a) memset(a,0,sizeof(a))
const int N=20003;
struct kk{
int to,ne;
}e[50003];
int n,x,y,low[N],dfn[N],tot,tim,fl,h[N],in[N],fa[N],cnt,T,i;
void clear(){
tim=tot=cnt=0;
M(low);M(dfn);M(h);M(in);M(fa);
}
void add(int x,int y){
e[++tot].to=y;
e[tot].ne=h[x];
h[x]=tot;
}
bool find(int x,int y){
while (fa[x]!=y){
if (++in[x]>1) return 0;
x=fa[x];
}
return 1;
}
bool tarjan(int u){
low[u]=dfn[u]=++tim;
for (int i=h[u];i;i=e[i].ne){
int v=e[i].to;
if (!dfn[v]){
fa[v]=u;
if (!tarjan(v)) return 0;
low[u]=min(low[u],low[v]);
}
else{
if (!find(u,v)) return 0;
low[u]=min(low[u],dfn[v]);
}
}
if (low[u]==dfn[u])
if (++cnt>1) return 0;
return 1;
}
int main(){
scanf("%d",&T);
while (T--){
scanf("%d",&n);
clear();
while (1){
scanf("%d%d",&x,&y);
if (!x && !y) break;
add(x,y);
}
fl=1;
for (i=0;i<n;i++)
if (!dfn[i])
if (!tarjan(i)){
fl=0;
break;
}
printf("%s\n",fl?"YES":"NO");
}
}
poj3592
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define M(a) memset(a,0,sizeof(a))
const int N=1603,M=5003;
struct kk{
int to,ne,w;
}e[M],a[M];
int low[N],dfn[N],in[N],vis[N],scc[N],val[N],v[N],h[M],head[M],tim,cnt,i,j,x,y,n,m,pos,T,tot,tot1,st[N],top,dis[N];
char s[43][43];
queue<int>q;
void init(){
tim=cnt=tot=tot1=top=0;
M(low);M(dfn);M(in);M(vis);M(scc);M(val);M(v);M(h);M(head);
}
void add(int x,int y){
a[++tot]=(kk){y,head[x],0};
head[x]=tot;
}
void add2(int x,int y,int z){
e[++tot1]=(kk){y,h[x],z};
h[x]=tot1;
}
void tarjan(int u){
low[u]=dfn[u]=++tim;
in[u]=1;st[top++]=u;
for (int i=head[u];i;i=a[i].ne){
int v=a[i].to;
if (!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]);
else if (in[v]) low[u]=min(low[u],dfn[v]);
}
if (low[u]==dfn[u]){
int x;cnt++;
do{
x=st[--top];
in[x]=0;
scc[x]=cnt;
val[cnt]+=v[x];
}while (x!=u);
}
}
int spfa(int s){
q.push(s);
memset(dis,-63,sizeof(dis));
dis[s]=0;
while (!q.empty()){
int u=q.front();q.pop();vis[u]=0;
for (int i=h[u];i;i=e[i].ne){
int v=e[i].to;
if (dis[v]<dis[u]+e[i].w){
dis[v]=dis[u]+e[i].w;
if (!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
int ans=-1;
for (int i=1;i<=cnt;i++) ans=max(ans,dis[i]);
return ans+val[s];
}
int main(){
scanf("%d",&T);
while (T--){
init();
scanf("%d%d",&n,&m);
for (i=0;i<n;i++) scanf("%s",s[i]);
for (i=0;i<n;i++)
for (j=0;j<m;j++){
pos=i*m+j;
if (s[i][j]=='#') v[pos]=0;
else{
if (i<n-1 && s[i+1][j]!='#') add(pos,pos+m);
if (j<m-1 && s[i][j+1]!='#') add(pos,pos+1);
if (s[i][j]=='*'){
scanf("%d%d",&x,&y);
v[pos]=0;
if (s[x][y]!='#') add(pos,x*m+y);
}else v[pos]=s[i][j]^48;
}
}
for (i=0;i<n*m;i++)
if (!dfn[i]) tarjan(i);
for (i=0;i<n*m;i++)
for (j=head[i];j;j=a[j].ne)
if (scc[i]!=scc[a[j].to]) add2(scc[i],scc[a[j].to],val[scc[a[j].to]]);
M(vis);
printf("%d\n",spfa(scc[0]));
}
}
lca:
学习博客
HDU 2586 How far way
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=40003;
#define M(a) memset(a,0,sizeof(a))
struct node{
int to,ne,id,w;
}e[N*2],que[403];
int T,n,m,i,x,y,z,fa[N],h[N],head[N],tot,tot1,vis[N],rank[N],dis[N];
void clear(){
dis[1]=tot=tot1=0;
for (int i=1;i<=n;i++) fa[i]=i;
M(vis);M(h);M(head);
}
void add(int x,int y,int z){
e[++tot]=(node){y,h[x],0,z};
h[x]=tot;
}
void add2(int x,int y,int z){
que[++tot1]=(node){y,head[x],z,0};
head[x]=tot1;
}
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void lca(int u){
vis[u]=1;
for (int i=h[u];i;i=e[i].ne){
int v=e[i].to;
if (!vis[v]){
dis[v]=dis[u]+e[i].w;
lca(v);
fa[v]=u;
}
}
for (int i=head[u];i;i=que[i].ne){
int v=que[i].to;
if (vis[v]) que[que[i].id].w=dis[u]+dis[v]-2*dis[find(v)];
}
}
int main(){
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&m);
clear();
for (i=1;i<n;i++) scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
for (i=1;i<=m;i++) scanf("%d%d",&x,&y),add2(x,y,i),add2(y,x,i);
lca(1);
for (i=1;i<=m;i++) printf("%d\n",que[i].w);
}
}
小机房的树
#include<bits/stdc++.h>
using namespace std;
const int N=50003;
struct node{
int to,ne,id,w;
}e[N*2],que[N*3];
int T,n,m,i,x,y,z,fa[N],h[N],head[N],tot,tot1,vis[N],dis[N];
void add(int x,int y,int z){
e[++tot]=(node){y,h[x],0,z};
h[x]=tot;
}
void add2(int x,int y,int z){
que[++tot1]=(node){y,head[x],z,0};
head[x]=tot1;
}
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void lca(int u){
vis[u]=1;
for (int i=h[u];i;i=e[i].ne){
int v=e[i].to;
if (!vis[v]){
dis[v]=dis[u]+e[i].w;
lca(v);
fa[v]=u;
}
}
for (int i=head[u];i;i=que[i].ne){
int v=que[i].to;
if (vis[v]) que[que[i].id].w=dis[u]+dis[v]-2*dis[find(v)];
}
}
int main(){
scanf("%d",&n);
for (i=1;i<n;i++) fa[i]=i;
for (i=1;i<n;i++) scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
scanf("%d",&m);
for (i=1;i<=m;i++) scanf("%d%d",&x,&y),add2(x,y,i),add2(y,x,i);
lca(0);
for (i=1;i<=m;i++) printf("%d\n",que[i].w);
}
HDu4547
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<iostream>
using namespace std;
const int N=100003;
#define M(a) memset(a,0,sizeof(a))
int T,s,e,i,vis[N],fa[N],in[N],tot,head[N],dis[N],m,cnt,n;
string s1,s2;
vector<int>G[N];
map<string,int>mp;
struct node{
int to,ne,id,lca;
}que[N*2];
struct kk{
int u,v,lca;
}edge[N*2];
void init(){
mp.clear();
tot=cnt=0;
for (int i=0;i<=n;i++){
G[i].clear();
fa[i]=i;
}
M(in);M(vis);
memset(head,-1,sizeof(head));
}
void add(int x,int y,int z){
que[tot]=(node){y,head[x],z,0};
head[x]=tot++;
}
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void lca(int u){
vis[u]=1;
for (int i=0;i<G[u].size();i++){
int v=G[u][i];
if (!vis[v]){
dis[v]=dis[u]+1;
lca(v);
fa[v]=u;
}
}
for (int i=head[u];i!=-1;i=que[i].ne){
int v=que[i].to;
if (vis[v]) edge[que[i].id].lca=que[i].lca=que[i^1].lca=find(v);
}
}
int main(){
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&m);
init();
for (i=1;i<n;i++){
cin>>s1>>s2;
if (!mp[s1]) mp[s1]=++cnt;
s=mp[s1];
if (!mp[s2]) mp[s2]=++cnt;
e=mp[s2];
G[s].push_back(e);
G[e].push_back(s);
in[s]++;
}
for (i=0;i<m;i++){
cin>>s1>>s2;
s=mp[s1];e=mp[s2];
add(s,e,i);add(e,s,i);
edge[i].u=s;edge[i].v=e;
}
for (i=1;i<=n;i++)
if (!in[i]) break;
lca(i);
for (i=0;i<m;i++) printf("%d\n",edge[i].u!=edge[i].v?dis[edge[i].u]-dis[edge[i].lca]+(edge[i].v!=edge[i].lca):0);
}
}