0
点赞
收藏
分享

微信扫一扫

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;
}



举报

相关推荐

0 条评论