- 基本..方法?
- 两道题吧
- poj1486
- 洛谷3731
大概就是先求出最大匹配(网络流…匈牙利会错【捂脸】),然后在残留网络上跑tarjan。然后最后看最初匹配中每条边的是不是在一个强连通里,如果不在那它就是最大匹配必须边
emmm只能二分图中…
不过这两道题啊…不是一天写的【捂脸】..风格看起来有很多差别【捂脸】
#include
#include
#include
#include
using namespace std;
#define N 100
#define inf 0x7fffffff
struct node{int x,y,z,next;}mp[N*N],b[N];
struct node1{int x1,x2,y1,y2;}a[N];
int n,num,t,T=0,h[N],d[N],cur[N],dfn[N],low[N],belong[N],vis[N],stack[N],scc,tot,top,ans;
bool cmp(node x,node y){return x.xvoid insert(int x,int y){
mp[++num].x=x;mp[num].y=y;mp[num].z=1;mp[num].next=h[x];h[x]=num;
mp[++num].x=y;mp[num].y=x;mp[num].z=0;mp[num].next=h[y];h[y]=num;
}
bool bfs(){
memset(d,0,sizeof(d));d[0]=1;
queue<int>q;q.push(0);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=h[u];i;i=mp[i].next){
int v=mp[i].y;
if(mp[i].z && !d[v]){
d[v]=d[u]+1;
q.push(v);
}
}
}return d[t];
}
int dfs(int x,int s1){
if(x==t || !s1) return s1;
int s2=s1;
for(int &i=cur[x];i;i=mp[i].next){
int y=mp[i].y;
if(d[y]==d[x]+1 && mp[i].z){
int s=dfs(y,min(mp[i].z,s1));
mp[i].z-=s;mp[i^1].z+=s;s1-=s;
if(!s) d[y]=0;
if(!s1) return s2;
}
}return s2-s1;
}
void tarjan(int x){
dfn[x]=++tot;low[x]=tot;vis[x]=1;stack[++top]=x;
for(int i=h[x];i;i=mp[i].next){
int y=mp[i].y;if(!mp[i].z) continue;
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}else if(vis[y]) low[x]=min(low[x],dfn[y]);
}if(low[x]==dfn[x]){
belong[x]=++scc;vis[x]=0;
while(stack[top]!=x){
belong[stack[top]]=scc;
vis[stack[top--]]=0;
}top--;
}
}
int main(){
while(scanf("%d",&n) && n>0){
T++;printf("Heap %d\n",T);
memset(h,0,sizeof(h));num=1;t=2*n+1;
for(int i=1;i<=n;i++) scanf("%d%d%d%d",&a[i].x1,&a[i].x2,&a[i].y1,&a[i].y2);
for(int i=1;i<=n;i++){
int x,y;scanf("%d%d",&x,&y);
for(int j=1;j<=n;j++) if(a[j].x1<=x && x<=a[j].x2 && a[j].y1<=y && y<=a[j].y2) insert(j,i+n);
}
for(int i=1;i<=n;i++) insert(0,i),insert(i+n,2*n+1);
ans=0;while(bfs()){memcpy(cur,h,sizeof(h));ans+=dfs(0,inf);}
if(ans!=n){printf("none\n\n");break;}
memset(dfn,0,sizeof(dfn));scc=top=tot=ans=0;
for(int i=1;i<=t;i++) if(!dfn[i]) tarjan(i);
memset(b,0,sizeof(b));
for(int i=2;i<=num;i+=2){
int x=mp[i].x,y=mp[i].y;if(mp[i].z || x==0 || y==t)continue;
if(belong[x]!=belong[y]) b[++ans].x=x,b[ans].y=y-n;
}sort(b+1,b+ans+1,cmp);
if(ans==0) printf("none\n");
else{
for(int i=1;i<=ans;i++) printf("(%c,%d) ",b[i].x+'A'-1,b[i].y);printf("\n");
}printf("\n");
}
return 0;
}
#include
#include
#include
#include
using namespace std;
#define N 11000
#define M 200000
#define inf 0x7fffffff
struct node{int x,y,next;}edge[2*M];
struct node1{int x,y,z,next;}mp[2*M];
struct node2{int x,y;}ans[M];
int n,m,num=0,cnt=1,nn=0,tot=0,top=0,scc=0,h1[N],h[N],d[N],b[N],cur[N],dfn[N],low[N],belong[N],vis[N],stack[N];
bool cmp(node2 x,node2 y){return x.xvoid insert(int x,int y){
edge[++num].x=x;edge[num].y=y;edge[num].next=h1[x];h1[x]=num;
edge[++num].x=y;edge[num].y=x;edge[num].next=h1[y];h1[y]=num;
}
int add(int x,int y,int z){
mp[++cnt].x=x;mp[cnt].y=y;mp[cnt].z=z;mp[cnt].next=h[x];h[x]=cnt;
mp[++cnt].x=y;mp[cnt].y=x;mp[cnt].z=0;mp[cnt].next=h[y];h[y]=cnt;
}
void dfs(int x){
for(int i=h1[x];i;i=edge[i].next){
int y=edge[i].y;
if(b[y]==-1){b[y]=b[x]^1;dfs(y);}
}
}
bool bfs(){
memset(d,0,sizeof(d));d[0]=1;
queue<int>q;q.push(0);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=h[u];i;i=mp[i].next){
int v=mp[i].y;
if(!d[v] && mp[i].z){
d[v]=d[u]+1;
q.push(v);
}
}
}return d[n+1];
}
int dfs(int x,int s1){
if(x==n+1 || !s1) return s1;
int s2=s1;
for(int &i=cur[x];i;i=mp[i].next){
int y=mp[i].y;
if(mp[i].z && d[y]==d[x]+1){
int s=dfs(y,min(mp[i].z,s1));
s1-=s;mp[i].z-=s;mp[i^1].z+=s;
if(!s) d[y]=0;
if(!s1) return s2;
}
}return s2-s1;
}
void tarjan(int x){
dfn[x]=++tot;low[x]=tot;vis[x]=1;stack[++top]=x;
for(int i=h[x];i;i=mp[i].next){
int y=mp[i].y;if(!mp[i].z) continue;
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}else if(vis[y]) low[x]=min(low[x],dfn[y]);
}if(dfn[x]==low[x]){
vis[x]=0;belong[x]=++scc;
while(stack[top]!=x){
vis[stack[top]]=0;
belong[stack[top--]]=scc;
}top--;
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y;scanf("%d%d",&x,&y);
insert(x,y);
}
memset(b,-1,sizeof(b));
for(int i=1;i<=n;i++)
if(b[i]==-1){
b[i]=0;
dfs(i);
}
for(int i=1;i<=2*m-1;i+=2){
int x=edge[i].x,y=edge[i].y;
if(!b[x]) add(x,y,1);
else add(y,x,1);
}
for(int i=1;i<=n;i++) if(b[i]) add(i,n+1,1);else add(0,i,1);
while(bfs()){memcpy(cur,h,sizeof(cur));dfs(0,inf);}
for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
for(int i=3;i<=2*m+1;i+=2)
if(mp[i].z && belong[mp[i].x]!=belong[mp[i].y]){
if(mp[i].xelse ans[++nn].x=mp[i].y,ans[nn].y=mp[i].x;
}sort(ans+1,ans+nn+1,cmp);
printf("%d\n",nn);
for(int i=1;i<=nn;i++) printf("%d %d\n",ans[i].x,ans[i].y);
return 0;
}