08合肥网络预选

来源:互联网 发布:java线程池和队列 编辑:程序博客网 时间:2024/06/10 04:38

http://acm.pku.edu.cn/JudgeOnline/problem?id=3692求其补图再进行二分匹配#include <iostream>#include <vector>using namespace std;#define N 210vector<int> v[N];int g[N][N],q[N], pv[N], ma[N], mb[N];int match(int nva, int nvb) // nva: |X|, nvb: |Y|{ int i, j, x, qs, qe, res = 0; memset(ma, -1, sizeof(ma)); memset(mb, -1, sizeof(mb)); for (i = 0; i < nva; i++) { // vertex: 0 ~ n-1 qs = qe = 0; for (j = 0; j < nvb; j++) pv[j] = -2; for (j = 0; j < v[i].size(); j++) { pv[v[i][j]] = -1; q[qe++] = v[i][j]; } while (qs < qe) { if (-1 == mb[x = q[qs]]) break; for (qs++, j = 0; j <v[ mb[x]].size(); j++) if(-2 == pv[v[mb[x]][j]] ) { pv[v[mb[x]][j]] = x; q[qe++] = v[mb[x]][j]; } } if (qs == qe) continue; while (pv[x] > -1) { ma[ mb[ pv[x] ] ] = x; mb[x] = mb[ pv[x] ]; x = pv[x]; } mb[x] = i; ma[i] = x; res++; } return res;}int main(){ int lc=1; int M,i,j,a,b,G,B; while(scanf("%d%d%d",&G,&B,&M),G) { for(i=0;i<G;i++) for(j=0;j<B;j++) g[i][j]=1; while(M--) { scanf("%d%d",&a,&b); g[a-1][b-1]=0; } for(i=0;i<G;i++) v[i].clear(); for(i=0;i<G;i++) for(j=0;j<B;j++) if(g[i][j]) v[i].push_back(j); printf("Case %d: %d\n",lc++,G+B-match(G,B)); } return 0;}

http://acm.pku.edu.cn/JudgeOnline/problem?id=3697

题意:

☆原给定一个完全图,节点数最多10000,告诉你一些损坏了的边,求节点1所在连通图除1外的节点数

★最开始直接申请一个bool[10000][10000],可是直接RE。后只好改为如下,因而时间不尽人意。

代码:

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

vector<int> v[10001];
queue<int> q1,q2;
int main()
{
int ll=0;
int n,m;
int i,a,b,num,t,t1,cur,l;
while(scanf("%d %d",&n,&m),n)
{
   for(i=1;i<=n;i++)
    v[i].clear();
   for(i=1;i<=m;i++)
   {
    scanf("%d%d",&a,&b);
    v[a].push_back(b);
    v[b].push_back(a);
   }
   if(m<n-1){
    printf("Case %d: %d\n",++ll,n-1);
    continue;
   }
   for(i=1;i<=n;i++)
    sort(v[i].begin(),v[i].end());
   while(!q1.empty())
    q1.pop();
   while(!q2.empty())
    q2.pop();
   for(i=2;i<=n;i++)
    q1.push(i);
   q2.push(1);
   num=n-1;
   while(!q2.empty())
   {
    t=q2.front();
    q2.pop();
    cur=num;
    l=0;
    while(cur)
    {
     t1=q1.front();
     q1.pop();
     while(l<v[t].size()&&v[t][l]<t1){
      l++;
     }
     if(l<v[t].size()&&v[t][l]==t1){
      q1.push(t1);
     }
     else{
      q2.push(t1);
      num--;
     }
     cur--;
    }
   }
   printf("Case %d: %d\n",++ll,n-num-1);
}
return 0;
}

原创粉丝点击