【查分约束】我爱你啊
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的结果;
当我们把上面的问题转化为图时,如下
View Code
我爱你啊
【题目描述】
呐,贵树真的是一个很帅的男孩子呢,所以好多女孩都给他写至少一封
了情书。那每个女孩给了贵树写了多少情书呢?我们不知道,但是我们知
道一些女孩子写情书数量的关系,你的任务是推断出贵树最少受到了多少
情书。
【输入文件】
输入的第一行为两个整数 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
相关文章推荐
- Opencv提取不规则ROI
- TIMIT语音库(续)
- 4.数据结构之通用链表实现
- 阿里云云服务器硬盘分区及挂载
- 关 于 解 析 php 的 问 题
- 单点登录
- 【Java】双等号和equals的区别
- UVa 1297 - The Minimum Number of Rooks
- C#事件(event)解析
- NSFileManager的理解
- Makefile自动生成工具-----autotools的使用(详细)
- MySQL备份l脚本
- Leetcode (1) Two Sum 解题报告
- spring中常用的util
- jquery--fullPage.js
- mydbtest文档
- android 根据字母排序ListView item数据
- [LeetCode-225] Implement Stack using Queues(两个队列实现栈)
- 【转】PLSQL Developer使用技巧整理
- nginx 使用配置知识