POJ 2723
逻辑错误的代码
1 //想了很久,发现自己做这道题时犯了一个大BUG。我的思路是,把一组钥匙看成一对X,-X。把 2 //门确定的关系连边。其实这样是有错的,因为边的意义是“必须”,而实际上,门确定的只是矛盾 3 //关系。不是必须是,不是门上锁其中一个选或不选就能影响到另一个。 4 5 #include <iostream> 6 #include <cstdio> 7 #include <cstring> 8 #include <algorithm> 9 using namespace std; 10 11 const int MAXN=3200; 12 const int MAXM=8000; 13 14 int bel[MAXN],head[MAXN],dfn[MAXN],low[MAXN],st[MAXN],stop,index,tot; 15 int belong[MAXN],pat; 16 bool stack[MAXN]; 17 18 struct { 19 int u,v; 20 int next,Id; 21 }edge[MAXM]; 22 int n,m; 23 24 void addedge(int u,int v){ 25 edge[tot].u=u; 26 edge[tot].v=v; 27 edge[tot].Id=tot; 28 edge[tot].next=head[u]; 29 head[u]=tot++; 30 } 31 32 void init(){ 33 for(int i=0;i<n*2;i++){ 34 dfn[i]=low[i]=0; 35 stack[i]=false; 36 belong[i]=-1; 37 } 38 stop=0; index=0; pat=-1; 39 } 40 41 void tarjan(int u,int limited){ 42 int v; 43 dfn[u]=low[u]=++index; 44 st[stop++]=u; 45 stack[u]=true; 46 for(int e=head[u];e!=-1;e=edge[e].next){ 47 if(edge[e].Id<=limited){ 48 v=edge[e].v; 49 if(dfn[v]==0){ 50 tarjan(v,limited); 51 low[u]=min(low[u],low[v]); 52 } 53 else if(stack[v]){ 54 low[u] = min(low[u], dfn[v]); 55 } 56 } 57 } 58 if(dfn[u]==low[u]){ 59 pat++; 60 do{ 61 v=st[--stop]; 62 stack[v]=false; 63 belong[v]=pat; 64 }while(u!=v); 65 } 66 } 67 68 bool slove(int mid){ 69 init(); 70 for(int i=0;i<2*n;i++){ 71 if(dfn[i]==0){ 72 tarjan(i,mid); 73 } 74 } 75 bool flag=true; 76 for(int i=0;i<n;i++){ 77 if(belong[i]==belong[2*i+1]){ 78 flag=false; 79 break; 80 } 81 } 82 return flag; 83 } 84 85 int main(){ 86 int u,v,t; int s1,s2; 87 while(scanf("%d%d",&n,&m)!=EOF){ 88 if(n==0&&m==0) break; 89 for(int i=0;i<=2*n;i++) 90 head[i]=-1; 91 tot=1; 92 for(int i=0;i<n;i++){ 93 scanf("%d%d",&u,&v); 94 bel[u]=2*i; bel[v]=2*i+1; 95 } 96 for(int i=1;i<=m;i++){ 97 scanf("%d%d",&u,&v); 98 s1=bel[u]; s2=bel[v]; 99 addedge(s1^1,s2); 100 addedge(s2^1,s1); 101 } 102 int lown,high,mid; 103 lown=1;high=m; int ans; 104 while(lown<=high){ 105 mid=(lown+high)/2; 106 if(slove(mid*2)){ 107 // cout<<mid<<endl; 108 ans=mid; lown=mid+1; 109 } 110 else high=mid-1; 111 } 112 printf("%d\n",ans); 113 } 114 return 0; 115 }
别人的代码。已明白错在哪里。。。只是不想写了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #define MAXN 5005 8 #define MAXM 50005 9 #define INF 1000000000 10 using namespace std; 11 struct Edge 12 { 13 int v, next; 14 }edge[MAXM]; 15 int n, m, e; 16 int top, scc, index; 17 int low[MAXN], dfn[MAXN], instack[MAXN]; 18 int head[MAXN], st[MAXN], fa[MAXN]; 19 int a[MAXN], b[MAXN], hash[MAXN]; 20 int x[MAXN], y[MAXN]; 21 void init() 22 { 23 top = scc = index = e = 0; 24 memset(head, -1, sizeof(head)); 25 memset(dfn, 0, sizeof(dfn)); 26 memset(instack, 0, sizeof(instack)); 27 } 28 void insert(int x, int y) 29 { 30 edge[e].v = y; 31 edge[e].next = head[x]; 32 head[x] = e++; 33 } 34 void tarjan(int u) 35 { 36 low[u] = dfn[u] = ++index; 37 instack[u] = 1; 38 st[++top] = u; 39 int v; 40 for(int i = head[u]; i != -1; i = edge[i].next) 41 { 42 v = edge[i].v; 43 if(!dfn[v]) 44 { 45 tarjan(v); 46 low[u] = min(low[u], low[v]); 47 } 48 else if(instack[v]) low[u] = min(low[u], dfn[v]); 49 } 50 if(dfn[u] == low[u]) 51 { 52 scc++; 53 do 54 { 55 v = st[top--]; 56 instack[v] = 0; 57 fa[v] = scc; 58 }while(v != u); 59 } 60 } 61 bool check(int n) 62 { 63 for(int i = 1; i <= n; i++) 64 if(fa[i] == fa[i + n]) return false; 65 return true; 66 } 67 void build(int bound) 68 { 69 init(); 70 for(int i = 1; i <= n; i++) 71 { 72 insert(a[i], b[i] + 2 * n); 73 insert(b[i], a[i] + 2 * n); 74 } 75 for(int i = 1; i <= bound; i++) 76 { 77 insert(x[i] + 2 * n, y[i]); 78 insert(y[i] + 2 * n, x[i]); 79 } 80 for(int i = 1; i <= 2 * n; i++) 81 if(!dfn[i]) tarjan(i); 82 } 83 void solve() 84 { 85 int ans = 0; 86 int low = 0, high = m; 87 while(low <= high) 88 { 89 int mid = (low + high) >> 1; 90 build(mid); 91 if(check(n * 2)) ans = max(ans, mid), low = mid + 1; 92 else high = mid - 1; 93 } 94 printf("%d\n", ans); 95 } 96 int main() 97 { 98 while(scanf("%d%d", &n, &m) != EOF) 99 { 100 if(n == 0 && m == 0) break; 101 for(int i = 1; i <= n; i++) 102 { 103 scanf("%d%d", &a[i], &b[i]); 104 a[i]++; b[i]++; 105 } 106 for(int i = 1; i <= m; i++) 107 { 108 scanf("%d%d", &x[i], &y[i]); 109 x[i]++; y[i]++; 110 } 111 solve(); 112 } 113 return 0; 114 }