nyoj 月老的难题

来源:互联网 发布:幼年秦义绝捏脸数据 编辑:程序博客网 时间:2024/04/29 20:30

http://acm.nyist.net/JudgeOnline/problem.php?pid=239


此题为二分最大匹配入门之必备习题之一!


话不多,上代码~

代码1:邻接表+匈牙利算法(邻接矩阵貌似会tle,此题数据量较大)

 #include<stdio.h> #include<stdlib.h> #include<string.h> struct EdgeNode {     int adjvex;    struct EdgeNode *next; }; struct VexNode {     struct EdgeNode *firstedge; }; struct VexNode alist[510]; int visit[501],match[510]; int find(int x) { <span style="white-space:pre"></span>int k;   <span style="white-space:pre"></span>struct EdgeNode *p;       <span style="white-space:pre"></span>p=alist[x].firstedge;    <span style="white-space:pre"></span>while (p)  <span style="white-space:pre"></span>{        <span style="white-space:pre"></span>k=p->adjvex;        <span style="white-space:pre"></span>if (!visit[k])     <span style="white-space:pre"></span>{<span style="white-space:pre"></span>visit[k]=1;  <span style="white-space:pre"></span>if (!match[k]||find(match[k]))          <span style="white-space:pre"></span>{            <span style="white-space:pre"></span>match[k]=x;            <span style="white-space:pre"></span>return 1;           <span style="white-space:pre"></span>}<span style="white-space:pre"></span>}       <span style="white-space:pre"></span>p=p->next;    <span style="white-space:pre"></span>}    <span style="white-space:pre"></span>return 0; } int main() { <span style="white-space:pre"></span>int n,t,k,i,ans,vi,vj;    <span style="white-space:pre"></span>struct EdgeNode *s; <span style="white-space:pre"></span>scanf("%d",&t);     <span style="white-space:pre"></span>while (t--) <span style="white-space:pre"></span> <span style="white-space:pre"></span>{        <span style="white-space:pre"></span>scanf("%d%d",&n,&k);       <span style="white-space:pre"></span>memset(alist,0,sizeof(alist));       <span style="white-space:pre"></span>memset(match,0,sizeof(match));        <span style="white-space:pre"></span>for (i=1;i<=k;i++)       <span style="white-space:pre"></span>{           <span style="white-space:pre"></span>scanf("%d%d",&vi,&vj);             <span style="white-space:pre"></span>s=(struct EdgeNode*)malloc(sizeof(struct EdgeNode));            <span style="white-space:pre"></span>s->adjvex=vj;           <span style="white-space:pre"></span>s->next=alist[vi].firstedge;           <span style="white-space:pre"></span>alist[vi].firstedge=s; <span style="white-space:pre"></span>}     <span style="white-space:pre"></span>for (i=1,ans=0;i<=n;i++)     <span style="white-space:pre"></span>{         <span style="white-space:pre"></span>memset(visit,0,sizeof(visit));       <span style="white-space:pre"></span>if (find(i)) ans++; <span style="white-space:pre"></span>       <span style="white-space:pre"></span>}         <span style="white-space:pre"></span>printf("%d\n",ans);    <span style="white-space:pre"></span>}    <span style="white-space:pre"></span>return 0; }
</pre><pre name="code" class="cpp"><img src="http://img.blog.csdn.net/20140807152147938?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQVExNEFRMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
</pre><pre name="code" class="cpp">
代码2:最大流
      思路:在原二分图的基础上,做几点修改,增加一个超级源点,并把源点和集合U(设二分图的点为两个集合U和V)中的每个点连成有向边,容量为1,再增加一个超级汇点,并把集合V中的每个点于汇点连成有向边,容量为1。
     #include<iostream>using namespace std;#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#define MAXM 30010 #define MAXN 1010#define oo 0x7fffffffstruct Dinic  {        struct node         {               int x,y,c,next;        }line[MAXM];           int Lnum,_next[MAXN],dis[MAXN];        void initial(int n)         {               for (int i=0;i<=n;i++) _next[i]=-1;               Lnum=-1;        }         void addline(int x,int y,int c)        {               line[++Lnum].next=_next[x],_next[x]=Lnum;               line[Lnum].x=x,line[Lnum].y=y,line[Lnum].c=c;               line[++Lnum].next=_next[y],_next[y]=Lnum;               line[Lnum].x=y,line[Lnum].y=x,line[Lnum].c=0;                     }        int BFS(int s,int e)        {                queue<int> Q;               while (!Q.empty()) Q.pop();               memset(dis,-1,sizeof(dis));               dis[s]=0;               Q.push(s);               while (!Q.empty())               {                     int h,k;                     h=Q.front(),Q.pop();                     if (h==e) return dis[e];                     for (k=_next[h];k!=-1;k=line[k].next)                        if (line[k].c && dis[line[k].y]==-1)                           dis[line[k].y]=dis[h]+1,Q.push(line[k].y);                                }                return false;        }        int dfs(int x,int flow,int e)          {                    if (x==e) return flow;                  int temp,cost=0;                 for (int k=_next[x];k!=-1;k=line[k].next)                 if (line[k].c && dis[line[k].y]==dis[x]+1)                 {                        temp=dfs(line[k].y,min(flow-cost,line[k].c),e);                         if (temp)                        {                               line[k].c-=temp,line[k^1].c+=temp;                               cost+=temp;                               if (flow==cost) return cost;                        }else dis[line[k].y]=0;                 }                 return cost;          }          int MaxFlow(int s,int e)        {               int MaxFlow=0;               while (BFS(s,e))                 MaxFlow+=dfs(s,oo,e);                return MaxFlow;        }  }T;   int main(){    int t;    scanf("%d",&t);     while (t--)          {          int n,k;          scanf("%d%d",&n,&k);          int N=2*n+1;          T.initial(N);          int v1[501],v2[501];          memset(v1,0,sizeof(v1));          memset(v2,0,sizeof(v2));           for (int i=0;i<k;++i)              {              int u,v;              scanf("%d%d",&u,&v);              T.addline(u,v+n,1);              if (v1[u]==0)                 {                 v1[u]=1;                 T.addline(0,u,1);                 }              if (v2[v]==0)                 {                 v2[v]=1;                 T.addline(v+n,N,1);                 }              }          int ans=T.MaxFlow(0,N);                     printf("%d\n",ans);          }    return 0;} #include<iostream>using namespace std;#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#define MAXM 30010 #define MAXN 1010#define oo 0x7fffffffstruct Dinic  {        struct node         {               int x,y,c,next;        }line[MAXM];           int Lnum,_next[MAXN],dis[MAXN];        void initial(int n)         {               for (int i=0;i<=n;i++) _next[i]=-1;               Lnum=-1;        }         void addline(int x,int y,int c)        {               line[++Lnum].next=_next[x],_next[x]=Lnum;               line[Lnum].x=x,line[Lnum].y=y,line[Lnum].c=c;               line[++Lnum].next=_next[y],_next[y]=Lnum;               line[Lnum].x=y,line[Lnum].y=x,line[Lnum].c=0;                     }        int BFS(int s,int e)        {                queue<int> Q;               while (!Q.empty()) Q.pop();               memset(dis,-1,sizeof(dis));               dis[s]=0;               Q.push(s);               while (!Q.empty())               {                     int h,k;                     h=Q.front(),Q.pop();                     if (h==e) return dis[e];                     for (k=_next[h];k!=-1;k=line[k].next)                        if (line[k].c && dis[line[k].y]==-1)                           dis[line[k].y]=dis[h]+1,Q.push(line[k].y);                                }                return false;        }        int dfs(int x,int flow,int e)          {                    if (x==e) return flow;                  int temp,cost=0;                 for (int k=_next[x];k!=-1;k=line[k].next)                 if (line[k].c && dis[line[k].y]==dis[x]+1)                 {                        temp=dfs(line[k].y,min(flow-cost,line[k].c),e);                         if (temp)                        {                               line[k].c-=temp,line[k^1].c+=temp;                               cost+=temp;                               if (flow==cost) return cost;                        }else dis[line[k].y]=0;                 }                 return cost;          }          int MaxFlow(int s,int e)        {               int MaxFlow=0;               while (BFS(s,e))                 MaxFlow+=dfs(s,oo,e);                return MaxFlow;        }  }T;   int main(){    int t;    scanf("%d",&t);     while (t--)          {          int n,k;          scanf("%d%d",&n,&k);          int N=2*n+1;          T.initial(N);          int v1[501],v2[501];          memset(v1,0,sizeof(v1));          memset(v2,0,sizeof(v2));           for (int i=0;i<k;++i)              {              int u,v;              scanf("%d%d",&u,&v);              T.addline(u,v+n,1);              if (v1[u]==0)                 {                 v1[u]=1;                 T.addline(0,u,1);                 }              if (v2[v]==0)                 {                 v2[v]=1;                 T.addline(v+n,N,1);                 }              }          int ans=T.MaxFlow(0,N);                     printf("%d\n",ans);          }    return 0;} 

    



0 0