HDU

来源:互联网 发布:代理商域名转到阿里云 编辑:程序博客网 时间:2024/06/03 18:01

关于二分图:把一个图的顶点划分为两个不相交集 U 和 V ,使得每一条边都分别连接U 、 V 中的顶点。如果存在这样的划分,则此图为一个二分图。
二分图最大匹配:给出一个二分图,尽量选最多的边,使得任意两条选中的边都没有公共点。
二分图详细讲解:(http://blog.csdn.net/pi9nc/article/details/11848327)

题意:
给出n个学生的排名范围,让你求最多多少人说真话,并写出字典序最大的那一个。
给出代码:(dfs实现)

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<iomanip>#include<cmath>#include<vector>#include<set>#include<queue>#define INF 0x3f3f3f3fusing namespace std;const int maxn=100005;//定义结构体class node{public:    int x,y;};node p[maxn];int vis[maxn];  //表示dian是否被搜索过,1表示搜索过,0表示未被搜索int match[maxn];//表示匹配的点的编号int res[maxn];   bool  dfs(int u){    for(int i=p[u].x;i<=p[u].y;i++)    {        if(!vis[i])           //如果i没有被搜索过        {            vis[i]=1;         //更新标记            if(match[i]==-1||dfs(match[i]))//如果i未在前一个匹配中,或者i在匹配中,但是从与i相邻的节点出发可以有增广路径              {                match[i]=u;   //更新匹配值                res[u]=1;                return true;            }        }    }    return false;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        int n;        scanf("%d",&n);        for(int i=0;i<n;i++)            scanf("%d%d",&p[i].x,&p[i].y);        memset(match,-1,sizeof(match));        memset(res,0,sizeof(res));        int cnt=0;        for(int i=n-1;i>=0;i--)        {            memset(vis,0,sizeof(vis));            if(dfs(i))                cnt++;        }        printf("%d\n",cnt);        for(int i=0;i<=n;i++)        {            if(res[i])            {                printf("%d",i+1);                if(i!=n-1)                    printf(" ");            }        }        printf("\n");    }}
原创粉丝点击