<!---Id=0 Type=Code S---> #include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<algorithm> #define maxn 5005 usingnamespace std; char ch; bool ok; voidread(int &x){ for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1; for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar()); if (ok) x=-x; } int n,k,x,con[maxn],cnt0,cnt1,list0[maxn],list1[maxn],num[maxn],boom[maxn]; bool g[maxn][maxn],bo[maxn]; structGraph{ int tot,now[maxn<<1],son[maxn*maxn],pre[maxn*maxn]; int idx,dfn[maxn<<1],low[maxn<<1],top,stack[maxn],cnt,bel[maxn<<1]; bool in[maxn<<1]; voidput(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;} voiddfs(int u){ dfn[u]=low[u]=++idx,stack[++top]=u,in[u]=1; for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) if (!dfn[v]) dfs(v),low[u]=min(low[u],low[v]); elseif (in[v]) low[u]=min(low[u],dfn[v]); if (dfn[u]==low[u]){ int v; ++cnt; do{v=stack[top--],in[v]=0,bel[v]=cnt;}while (v!=u); } } }G; intmain(){ read(n); for (int i=1;i<=n;i++){ read(k),con[i]=k; while (k--) read(x),g[i][x]=1; } for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (i!=j){ if (g[i][j]) G.put((i<<1)+1,j<<1); else G.put(i<<1,(j<<1)+1); } for (int i=2;i<=(n<<1)+1;i++) if (!G.dfn[i]) G.dfs(i); for (int i=1;i<=n;i++){ if (G.bel[i<<1]==G.bel[(i<<1)+1]){puts("0");return0;} if (G.bel[i<<1]<G.bel[(i<<1)+1]) list0[++cnt0]=i; else bo[i]=1,list1[++cnt1]=i; } int ans=(cnt0&&cnt1); for (int i=1;i<=cnt0;i++) for (int j=1;j<=cnt1;j++) if (g[list0[i]][list1[j]]) num[list0[i]]++,boom[list0[i]]=list1[j]; for (int i=1;i<=cnt1;i++) for (int j=1;j<=cnt0;j++) if (!g[list1[i]][list0[j]]) num[list1[i]]++,boom[list1[i]]=list0[j]; for (int i=1;i<=n;i++) if (num[i]==1){ if (num[boom[i]]==1&&boom[i]>i&&boom[boom[i]]==i) ans++; elseif (!num[boom[i]]) ans++; } int t0=0,t1=0; for (int i=1;i<=n;i++) if (!num[i]){ if ((bo[i]&&cnt1>1)||(!bo[i]&&cnt0>1)) ans++; if (bo[i]) t1++; else t0++; } ans+=t1*t0; printf("%d\n",ans); return0; }
标志放置
一张无向图,对于边 (x,y),如果满足如下条件:
从 x 走到 y 后如果不掉头(即将行进的方向调转 180°,你可以认为从一条路转到另一条不同的路时不会出现这种情况)则无法回到 x,
如果能从 y 不掉头走到一条边 (x′,y′) 的 x′ 端,并且 x′ 这段有标记,则无需在 (x,y) 的 x 端放置标记,我们认为这是“多余的”。
则在 (x,y) 这条边 x 这一侧放一个「此路不通」标志,请你求出所有「此路不通」标志的位置。
输入格式
输入的第一行包含两个整数 n,m ,分别代表图中地点的数目和街道的数目。
接下来 m 行,每行包含两个整数 v,w ,表示这条街道连接了 u,v 两个地点。
输入保证不会给出重复的街道。
输出格式
第一行输出一个数字 k ,代表安装的「此路不通」标志的数量。
接下来 k 行,每行输出两个整数 v,w ,代表在连接 v,w 的街道的 v 入口处安装一个「此路不通」标志。
<!---Id=0 Type=Code S---> #include<iostream> #include<cstdio> #include<queue> #include<vector> #include<algorithm> usingnamespace std;queue<int> q;pair<int,int> ans[500005]; int _ans=0,deg[500005],inq[500005];vector<int> g[500005]; intmain(){ int n,m,u,v;scanf("%d%d",&n,&m); for (registerint i=0;i<m;++i) scanf("%d%d",&u,&v), g[u].push_back(v),g[v].push_back(u),++deg[u],++deg[v]; for (registerint i=1;i<=n;++i) sort(g[i].begin(),g[i].end()); while (!q.empty()) q.pop(); for (registerint i=1;i<=n;++i) if (deg[i]==1) inq[i]=true,q.push(i); while (!q.empty()) {int cur=q.front();q.pop(); for (registerint ot:g[cur]) if (!inq[ot]&&--deg[ot]==1) inq[ot]=true,q.push(ot); }while (!q.empty()) q.pop(); for (registerint i=1;i<=n;++i) inq[i]=0; for (registerint i=1;i<=n;++i) if (deg[i]>1) inq[i]=1,q.push(i);else inq[i]=0; while (!q.empty()) {int cur=q.front();q.pop(); for (registerint ot:g[cur]) if (!inq[ot]) inq[ot]=1,q.push(ot); }for (registerint i=1;i<=n;++i) for (registerint ot:g[i]) { if (!inq[i]&&g[i].size()==1) ans[++_ans]=make_pair(i,ot); if (inq[i]&°[i]>1&°[ot]==1) ans[++_ans]=make_pair(i,ot); }printf("%d\n",_ans); for (registerint i=1;i<=_ans;++i) printf("%d %d\n",ans[i].first,ans[i].second); return0; } <!---Id=0 Type=Code E--->
inlineboolbfs(int s,int t){ memset(deep,0x7f,sizeof(deep)); deep[s]=0; for (int i=1;i<=N;++i) cur[i]=point[i]; while (!q.empty()) q.pop(); q.push(s);
while (!q.empty()){ int now=q.front(); q.pop(); for (int i=point[now];i!=-1;i=nxt[i]) if (deep[v[i]]>inf&&remain[i]){ deep[v[i]]=deep[now]+1; q.push(v[i]); } }
return deep[t]<inf; }
inlineintdfs(int now,int t,int limit){ if (!limit||now==t) return limit; int flow=0,f;
for (int i=cur[now];i!=-1;i=nxt[i]){ cur[now]=i; if (deep[v[i]]==deep[now]+1&&(f=dfs(v[i],t,min(limit,remain[i])))){ flow+=f; limit-=f; remain[i]-=f; remain[i^1]+=f; if (!limit) break; } } return flow; }
inlinevoiddinic(int s,int t){ while (bfs(s,t)) maxflow+=dfs(s,t,inf); }