2015 Multi-University Training Contest 2

5305:【题目链接】:click here~~

【题意】:

题意:

 给一个图,不存在重边。

任意两个人(结点)有线上或者线下的关系,但是每个人线上和线下关系的朋友必须一样多。

求有几种方案。

=====等效于对图的边黑白染色。每个点的黑色边和白色边要一样。

【思路】:

   特判如果存在边的度数为奇数的,直接输出0.

    只有八个人。实际上最复杂的情况是每个人的边数都是6条。那么枚举每个人,把他们的边染色。选出一半的边染成黑色。

   分析最复杂的情况C(3,6)*C(3,6)*C(2,4)*C(2,4)*C(1,2)*C(1,2)

为什么后面的C边数少了呢?因为之前枚举点的时候已经处理了这些边。所以后面就不用处理了。

剪枝:如果一个点的黑色边数 > 入度的一半,结束这次搜索

代码:

/************** 5305***************
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif

#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

using namespace std;

#define rep(i,j,k) for(int i=(int)j;i<(int)k;++i)
#define per(i,j,k) for(int i=(int)j;i>(int)k;--i)
#define lowbit(a) a&-a
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))

typedef long long LL;
typedef unsigned long long LLU;
typedef double db;
const int N=105;
const int inf=0x3f3f3f3f;

char str[N];
bool vis[N];

int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};
int dir8[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
int movv[5][2]= {{1,0},{0,1},{0,0},{-1,0},{0,-1}};

inline LL read()
{
    int c=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
    return c*f;
}

int n,m,t,res;

struct node
{
    int a,b;
} ww[N];

int sum[N];///总共的数目
int now[N]; ///当前的friend 数目
int out[N];///已经统计过的friend 数目

void dfs(int cnt)
{
    int j;
    if(cnt==m){
        for(j=1; j<=n; ++j) if(now[j]*2!=sum[j]) break;
        if(j>n) res++;
    }

    int x=ww[cnt].a;
    int y=ww[cnt].b;

    if(sum[x]-out[x]+now[x]<sum[x]/2||sum[y]+now[y]-out[y]<sum[y]/2) return;

    out[x]++,out[y]++;
    if(now[x]+1<=(sum[x]/2)&&now[y]+1<=(sum[y]/2)){
        now[x]++,now[y]++;
        dfs(cnt+1);
        now[x]--,now[y]--;
    }
    dfs(cnt+1);
    out[x]--,out[y]--;
}

int main()
{
    t=read();
    while(t--)
    {
        n=read(),m=read();
        mem(sum,0);
        mem(now,0);
        mem(out,0);
        for(int i=0; i<m; ++i){
            ww[i].a=read();
            ww[i].b=read();
            sum[ww[i].a]++;
            sum[ww[i].b]++;
        }
        if(m==0){
            puts("1");
            continue;
        }
        int f=1;
        for(int i=1; i<=n; ++i)
            if(sum[i]%2==1){
                puts("0");
                f=0;;
                break;
            }
        if(f){
            res=0;
            dfs(0);
            printf("%d\n",res);
        }
    }
    return 0;
}

别人的代码参考:

#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<cmath>  
#include<queue>  
#include<stack>  
#include<vector>  
#include<set>  
#include<map>  
  
#define L(x) (x<<1)  
#define R(x) (x<<1|1)  
#define MID(x,y) ((x+y)>>1)  
  
#define eps 1e-8  
using namespace std;  
  
typedef __int64 LL;  
  
#define N 100  
  
int x[N],y[N],in[N],on[N],off[N];  
int n,m;  
int ans;  
  
bool judge()  
{  
    if(m&1) return false;  
    for(int i=1;i<=n;i++) if(in[i]&1) return false;  
    return true;  
}  
  
void dfs(int pos)  
{  
    if(pos==m)  
    {  
        ans++;  
        return ;  
    }  
    int u=x[pos],v=y[pos];  
    if(on[u]<in[u]/2&&on[v]<in[v]/2)  //这个边为online 边  
    {  
        on[u]++;  
        on[v]++;  
        dfs(pos+1);  
        on[u]--;  
        on[v]--;  
    }  
  
    if(off[u]<in[u]/2&&off[v]<in[v]/2) //这个边为off边  
    {  
        off[u]++;  
        off[v]++;  
        dfs(pos+1);  
        off[u]--;  
        off[v]--;  
    }  
}  
int main()  
{  
    int i,j,t;  
    scanf("%d",&t);  
    while(t--)  
    {  
        scanf("%d%d",&n,&m);  
        memset(in,0,sizeof(in));  
        memset(on,0,sizeof(on));  
        memset(off,0,sizeof(off));  
  
        for(i=0;i<m;i++)  
        {  
            scanf("%d%d",&x[i],&y[i]);  
            in[x[i]]++;  
            in[y[i]]++;  
        }  
        ans=0;  
        if(!judge())  
        {  
            printf("0\n");  
            continue;  
        }  
        dfs(0);  
        printf("%d\n",ans);  
    }  
    return 0;  
}  


5302:【题目链接】:click here~~

【题意】:给你一个n*m的矩形,可以分成n*m个1*1的小矩形,再给你一个坐标(x,y),表示黑格子在n*m矩形中的位置,黑格子占一个1*1的小矩形的空间,用各种矩形去填充n*m矩形,(x,y)位置不能填,且每个去填充的小矩形都有一边是靠着n*m矩形的外框,求这些填充的小矩形在最小大小情况下的面积最大的矩形面积。

【思路】:要是填充的矩形大小最小,那么靠近边框的长度一定为1,所以只要判断在矩形内部的长度大小即可,矩形面积即为在大矩形内部的长度。

代码:

// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif

#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

using namespace std;

#define rep(i,j,k) for(int i=(int)j;i<(int)k;++i)
#define per(i,j,k) for(int i=(int)j;i>(int)k;--i)
#define lowbit(a) a&-a
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))

typedef long long LL;
typedef unsigned long long LLU;
typedef double db;
const int N=1e6+10;
const int inf=0x3f3f3f3f;

char str[N];
bool vis[N];

int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};
int dir8[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
int movv[5][2]= {{1,0},{0,1},{0,0},{-1,0},{0,-1}};

inline LL read()
{
    int c=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        c=c*10+ch-'0';
        ch=getchar();
    }
    return c*f;
}

char mon1[N],mon2[N];
int row,line,x,t,y,res;
int main()
{
    while(~scanf("%d%d%d%d",&row,&line,&x,&y)){
        if(row>line){
            swap(row,line);
            swap(x,y);
        }
        x=min(x,row-x+1);
        y=min(y,line-y+1);
        if(row==line&&(row%2==1)&&(x==y)&&x==((row+1)/2)){
            cout<<row/2<<endl;
            continue;
        }
        res=(row+1)/2;
        res=max(res,min(y,row-x));
        cout<<res<<endl;
    }
    return 0;
}


你可能感兴趣的:(多校联合)