您的位置:首页 > 其它

【查分约束】我爱你啊

2015-10-21 18:12 197 查看
某看了秒5而内心激动的人创作本题

我爱你啊

【题目描述】
呐,贵树真的是一个很帅的男孩子呢,所以好多女孩都给他写至少一封
了情书。那每个女孩给了贵树写了多少情书呢?我们不知道,但是我们知
道一些女孩子写情书数量的关系,你的任务是推断出贵树最少受到了多少
情书。
【输入文件】
输入的第一行为两个整数 N,K,表示一共 N 个女孩,知道 K 对关系
接下来 K 行,每行三个整数 t,A,B
如果 t=1,则表示 A 的情书和 B 的情书数量一样
如果 t=2,则表示 A 的情书少于 B 的情书数量
如果 t=3,则表示 A 的情书不少于 B 的情书数量
如果 t=4,则表示 A 的情书多于 B 的情书数量
如果 t=5,则表示 A 的情书不多于 B 的情书数量
【输出文件】
一行,表示贵树满足这些关系时最少情况下收到情书的数量。
如果这些关系不可能同时被满足,则输出 -1。
【样例输入】
5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
【样例输出】
11
【数据规模】
对于 30% 数据,保证 N  <=100
对于 100% 数据,保证 N  <=100000

考试时拿到这道题,已经想到了spfa算法,但是_(:з」∠)_因为没有学习查分约束,所以没有过(水了十分ORZ)

查分约束,如本题的这种问题类型。本质就是不等式组,求是否有解,或者解是多少的问题,神奇的是这是一个披着数学皮的……图论。

比如给出几个不等式:A-B>=q,B-C>=p,C-A<=r,求C-A的最大值

易得C-A的最大值是比较p+q和r的结果;

当我们把上面的问题转化为图时,如下

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,k;
struct node{
int to,next;
int value;
}e[100001];
int head[100001];
int m=0;
int queue[100001];
int q_head=0;
int q_tail=1;
int dis[100001];
bool v[100001];
void add(int u,int v,int w)//加边
{
m++;
e[m].to=v;
e[m].next=head[u];
e[m].value=w;
head[u]=m;
}
void read()
{
memset(v,0,sizeof(v));
memset(dis,0,sizeof(dis));
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) add(0,i,0);
for(int i=1;i<=k;i++)
{
int a,b,t;
scanf("%d%d%d",&t,&a,&b);
if(t==1)
{
add(a,b,0);
add(b,a,0);
}//如果相等,这条边就是一条无向边,不影响最终结果 ;
if(t==3)
{
add(b,a,0);
add(b,a,1);
}
if(t==5)
{
add(a,b,0);
add(a,b,1);
}
if(t==2) add(a,b,1);
if(t==4) add(b,a,1);//注意括号里a,b顺序的不同,这表现了不等式形式(x-y<=z→→y-x>=-z)的变化;
}
}
void spfa()//寻找最长路 ;
{
dis[0]=0;//因为找起点是很麻烦的,所以我们虚拟一个点 0 作为起点,使每个点到它的距离为 0,这样依然不影响结果;
v[0]=1;
queue[q_tail]=0;
while(q_tail>q_head)
{
int p=queue[++q_head];
v[p]=1;
int p1=head[p];
while(p1!=0)
{
if(dis[e[p1].to]<=dis[p]+e[p1].value)
{
dis[e[p1].to]=dis[p]+e[p1].value;
if(!v[e[p1].to])
{
queue[++q_tail]=e[p1].to;
v[e[p1].to]=1;
}
}
p1=e[p1].next;
}
}
int ans=n;//因为每个人至少一封,所以ans最小为 n ;
for(int i=1;i<=n;i++)
printf("i=%d dis=%d\n",i,dis[i]);
for(int i=1;i<=n;i++)
ans+=dis[i];    // 加上每一个点的最小值;
printf("%d ",ans);
}
int main()
{
read();
spfa();
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: