P2474 [SCOI2008]天平

题目背景

2008四川NOI省选

题目描述

你有n个砝码,均为1克,2克或者3克。你并不清楚每个砝码的重量,但你知道其中一些砝码重量的大小关系。你把其中两个砝码A 和B 放在天平的左边,需要另外选出两个砝码放在天平的右边。问:有多少种选法使得天平的左边重(c1)、一样重(c2)、右边重(c3)?(只有结果保证惟一的选法才统计在内)

输入输出格式

输入格式:

第一行包含三个正整数n,A,B(1<=A,B<=N,A 和B 不相等)。砝码编号

为1~N。以下n行包含重量关系矩阵,其中第i行第j个字符为加号“+”表示砝

码i比砝码j重,减号“-”表示砝码i比砝码j 轻,等号“=”表示砝码i和砝码

j一样重,问号“?”表示二者的关系未知。存在一种情况符合该矩阵。

输出格式:

仅一行,包含三个整数,即c1,c2和c3。

输入输出样例

输入样例#1: 复制

6 2 5
?+????
-?+???
?-????
????+?
???-?+
????-?
输出样例#1: 复制

1 4 1
输入样例#2: 复制

14 8 4
?+???++?????++
-??=?=???????=
??????????=???
?=??+?==??????
???-???-???-??
-=????????????
-??=???=?-+???
???=+?=???????
??????????????
??????+???????
??=???-????-??
????+?????+???
-?????????????
-=????????????
输出样例#2: 复制

18 12 11

说明

4<=n<=50

/*
w[i]<w[j]就连一条i->j的边
w[i]=w[j]就连一条双向边
跑Tarjan把图缩成有向无环图
最后入度为0的点的质量就是1,按拓排给其他的赋值为2,3
由于少考虑了一些情况,导致不合法的情况也会统计到答案中,所以炸了
*/
#include<iostream>
#include<cstdio>
#include<queue>
#define maxn 51
using namespace std;
int n,A,B,belong[maxn],wei[maxn],w[maxn],cnt,map[maxn][maxn],du[maxn];
int num,head[maxn],dfn[maxn],low[maxn],st[maxn],top,g,gr[maxn][maxn];
int Num,Head[maxn];
double vis[maxn];
struct node{
int to,pre;
}e[maxn*],E[maxn*];
char s[maxn];
void Insert(int from,int to){
e[++num].to=to;
e[num].pre=head[from];
head[from]=num;
}
void Insert2(int from,int to){
E[++Num].to=to;
E[Num].pre=Head[from];
Head[from]=Num;
}
void Tarjan(int u){
cnt++;
dfn[u]=low[u]=cnt;st[++top]=u;vis[u]=;
for(int i=head[u];i;i=e[i].pre){
int v=e[i].to;
if(!dfn[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v])low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
g++;
while(st[top]!=u){
int x=st[top];
top--;vis[x]=;
gr[g][++gr[g][]]=x;
belong[x]=g;
}
belong[u]=g;
gr[g][++gr[g][]]=u;
vis[u]=;
top--;
}
}
queue<int>q;
int main(){
freopen("Cola.txt","r",stdin);
scanf("%d%d%d",&n,&A,&B);
for(int i=;i<=n;i++){
scanf("%s",s+);
for(int j=;j<=n;j++){
if(s[j]=='-')map[i][j]=-,map[j][i]=;
if(s[j]=='+')map[i][j]=,map[j][i]=-;
if(s[j]=='=')map[i][j]=,map[j][i]=;
}
}
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
if(map[i][j]==)Insert(j,i);//i>j连一条从j指向i的边
if(map[i][j]==-)Insert(i,j);//i<j连一条从i指向j的边
if(map[i][j]==)Insert(i,j),Insert(j,i);
}
}
for(int i=;i<=n;i++)if(!dfn[i])Tarjan(i);
for(int i=;i<=g;i++){
for(int j=;j<=gr[i][];j++){
int now=gr[i][j];
for(int k=head[now];k;k=e[k].pre){
int to=e[k].to;
if(belong[now]!=belong[to])
Insert2(belong[now],belong[to]),du[belong[to]]++;
}
}
}
for(int i=;i<=g;i++){
if(du[i]==)q.push(i),wei[i]=;
}
while(!q.empty()){
int now=q.front();q.pop();
for(int i=Head[now];i;i=E[i].pre){
int to=E[i].to;
du[to]--;
if(du[to]==){
wei[to]=wei[now]+;
q.push(to);
}
}
}
for(int i=;i<=n;i++)w[i]=wei[belong[i]];
int c1=,c2=,c3=,sum=w[A]+w[B];
for(int i=;i<=n;i++){
if(i==A||i==B)continue;
for(int j=i+;j<=n;j++){
if(j==A||j==B)continue;
if(w[i]+w[j]<sum)c1+=;
if(w[i]+w[j]==sum)c2+=;
if(w[i]+w[j]>sum)c3+=;
}
}
cout<<c1<<' '<<c2<<' '<<c3;
}

20分 拓扑排序

/*
a+b>c+d可以转化为a-c>d-b,可以用差分约束求解
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 51
using namespace std;
int n,a,b,dx[maxn][maxn],dn[maxn][maxn];
char s[maxn];
int main(){
freopen("Cola.txt","r",stdin);
scanf("%d%d%d",&n,&a,&b);
for(int i=;i<=n;i++){
scanf("%s",s+);
for(int j=;j<=n;j++){
if(i==j||s[j]=='=')dx[i][j]=dn[i][j]=;
else if(s[j]=='+')dn[i][j]=,dx[i][j]=;
else if(s[j]=='-')dn[i][j]=-,dx[i][j]=-;
else dn[i][j]=-,dx[i][j]=;
}
}
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
if(k==i||k==j||i==j)continue;
dn[i][j]=max(dn[i][j],dn[i][k]+dn[k][j]);
dx[i][j]=min(dx[i][j],dx[i][k]+dx[k][j]);
}
int c1=,c2=,c3=;
for(int i=;i<=n;i++){
if(i==a||i==b)continue;
for(int j=;j<i;j++){
if(j==a||j==b)continue;
if(dn[a][i]>dx[j][b]||dn[b][i]>dx[j][a])c1++;
if(dn[i][a]>dx[b][j]||dn[i][b]>dx[a][j])c3++;
if((dn[a][i]==dx[a][i]&&dn[j][b]==dx[j][b]&&dn[a][i]==dn[j][b]) || (dn[a][j]==dx[a][j]&&dn[i][b]==dx[i][b]&&dn[a][j]==dn[i][b]))c2++;
}
}
printf("%d %d %d",c1,c2,c3);
}

100分 差分约束

洛谷P2474 [SCOI2008]天平的更多相关文章

  1. 洛谷2474 [SCOI2008] 天平 差分约束->枚举

    题目描述 你有n个砝码,均为1克,2克或者3克.你并不清楚每个砝码的重量,但你知道其中一些砝码重量的大小关系.你把其中两个砝码A 和B 放在天平的左边,需要另外选出两个砝码放在天平的右边.问:有多少种 ...

  2. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  3. BZOJ1079或洛谷2476 [SCOI2008]着色方案

    一道记忆化搜索 BZOJ原题链接 洛谷原题链接 发现对于能涂木块数量一样的颜色在本质上是一样的,所以可以直接压在一个状态,而这题的数据很小,直接暴力开\(6\)维. 定义\(f[a][b][c][d] ...

  4. 洛谷P2405 non天平

    题目背景 non最近正在为自己的体重而苦恼,他想称量自己的体重.于是,他找来一个天平与许多砝码. 题目描述 砝码的重量均是n的幂次,n^1.n^2.n^3.n^4.n^5的……non想知道至少要多少个 ...

  5. 洛谷 P2473 [SCOI2008]奖励关 解题报告

    P2473 [SCOI2008]奖励关 题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出\(k\)次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝 ...

  6. 洛谷 P2507 [SCOI2008]配对

    P2507 [SCOI2008]配对 题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值 ...

  7. 洛谷P2507 [SCOI2008]配对

    题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对. ...

  8. 洛谷2473(SCOI2008)奖励关

    题目:https://www.luogu.org/problemnew/show/P2473 因为可不可选此物与之前选过什么物品有关,所以状态可以记录成前面已经选过什么物品. 因为选不选此物与它带来的 ...

  9. 洛谷 P2473 [SCOI2008]奖励关(状压dp+期望)

    题面 luogu 题解 \(n \leq 15\) 状压 \(f[i][S]\)表示第\(i\)轮,吃过的集合为\(S\) 正着转移好像有点复杂 考虑逆推转移(正着转移应该也行) \(f[i][S]\ ...

随机推荐

  1. 【leetcode刷题笔记】Recover Binary Search Tree

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  2. LiveMediaStreamer

    LiveMediaStreamer is an open source multimedia framework that allows the manipulation of multiple au ...

  3. poj2395

      #include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib> ...

  4. POJ2774Long Long Message (后缀数组&后缀自动机)

    问题: The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to ...

  5. ACM学习历程—HDU5586 Sum(动态规划)(BestCoder Round #64 (div.2) 1002)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5586 题目大意就是把一段序列里面的数替换成f(x),然后让总和最大. 首先可以计算出初始的总和,以及每 ...

  6. ACM学习历程——ZOJ 3829 Known Notation (2014牡丹江区域赛K题)(策略,栈)

    Description Do you know reverse Polish notation (RPN)? It is a known notation in the area of mathema ...

  7. bzoj 2732: [HNOI2012]射箭 半平面交

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2732 题解: 这道题的做法我不想说什么了... 其他题解都有说做法... 即使是我上午做 ...

  8. bzoj 3533: [Sdoi2014]向量集 线段树维护凸包

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3533 题解: 首先我们把这些向量都平移到原点.这样我们就发现: 对于每次询问所得到的an ...

  9. delete操作符

    delete操作符通常用来删除对象的属性: Js代码     var o = { x: 1 }; delete o.x; // true o.x; // undefined 而不是一般的变量: Js代 ...

  10. Parallel Programming-Parallel.Invoke

    本文主要介绍Parallel.Invoke的使用. 一.使用例子 class ParallelInvoke { public void Action1() { Thread.Sleep(); Cons ...