BZOJ 3373: [Usaco2004 Mar]Lying Livestock 说谎的牲畜( 差分约束 )

本文介绍了一道经典的图论问题——Usaco2004Mar LyingLivestock,通过枚举每头牛并假设其说谎的方式,构建图模型并判断是否存在环来找出说谎的奶牛。详细阐述了问题背景、输入输出格式及算法实现过程。
摘要由CSDN通过智能技术生成

枚举每头牛, 假设它在说谎, 建图判圈就行了...为啥水题都没人来写.. 

------------------------------------------------------------------

#include<bits/stdc++.h>
 
using namespace std;
 
typedef pair<int, int> pii;
 
const int maxn = 109;
 
struct edge {
int to, w;
edge(int _t, int _w):to(_t), w(_w) {}
};
 
vector<edge> G[maxn];
vector<pii> cow[maxn];
bool vis[maxn], F;
int d[maxn], N;
  

void dfs(int x) {

vis[x] = true;
for(vector<edge>::iterator e = G[x].begin(); e != G[x].end(); e++) if(d[e->to] <= d[x] + e->w) {
   if(!vis[e->to]) {
d[e->to] = d[x] + e->w;
    dfs(e->to);
   } else
       F = true;
   if(F) break;
}
vis[x] = false;
}
 
void init() {
memset(vis, false, sizeof vis);
int q;
cin >> N >> q;
while(q--) {
int c, u, v;
scanf("%d%d%d", &c, &u, &v);
c--; u--; v--;
cow[c].push_back(make_pair(u, v));
}
}
 
void work() {
int ans = 0;
for(int i = 0; i < N; i++) {
memset(d, 0, sizeof d);
F = false;
for(int j = 0; j < N; j++)
   G[j].clear();
for(vector<pii>::iterator it = cow[i].begin(); it != cow[i].end(); it++)
   G[it->first].push_back(edge(it->second, 0));
for(int j = 0; j < N; j++) if(j != i)
for(vector<pii>::iterator it = cow[j].begin(); it != cow[j].end(); it++)
   G[it->second].push_back(edge(it->first, 1));
for(int j = 0; j < N; j++) {
if(F) break;
dfs(j);
}
if(!F) ans++;
}
cout << ans << "\n";
}
int main() {
init();
work();
return 0;
}

 

------------------------------------------------------------------

3373: [Usaco2004 Mar]Lying Livestock 说谎的牲畜

Time Limit: 10 Sec   Memory Limit: 128 MB
Submit: 24   Solved: 8
[ Submit][ Status][ Discuss]

Description

兽群中总是有一些麻烦制造者.约翰知道他的N(1≤N≤100)头奶牛中有一头总是说谎,其他的总是说真话.他想快速的找出这个麻烦制造者.为了实现这个目标,他一个一个的问这些奶牛Q(1≤Q≤1000)个关于它们吃草的简单问题(虽然大多数奶牛是诚实的但它们依旧很笨只能懂得一些关于食物的话题).
他将这些问题用以下的格式写了下来:
牛4说:牛5比牛10吃得多
牛6说:牛10比牛7吃得多
牛3说:牛2比牛6吃得多
牛1说:牛7比牛5吃得多
从这个例子中不难看出说谎的奶牛只有可能是4,6,1.你的任务是确定可能说谎的奶牛的个
数.可能说谎的奶牛是指如果这头奶牛说谎则输入数据中不存在矛盾.

Input

第1行:两个用空格分开的整数N和Q.第2到Q+1:每一行描述一个问题,由3个用空格隔开的整数A,B,C表示,意思是A说B牛吃的比C牛多.一头奶牛可能回答多次.

Output

仅一行一个整数即可能说谎的奶牛的头数.

Sample Input

3 4
3 1 2
1 3 1
1 3 2
2 2 1

Sample Output

2

样例说明
3头奶牛给出了4个回答.奶牛1说3>1,3>2,奶牛2说2>1,奶牛3说1>2.当然“>”的意思是“吃得多”. 显然,2号和3号的话是矛盾的.它们都有可能说谎.如果1号说谎则2,3都没说谎,那是不可能的.所以,1号说的一定是实话.

HINT

Source

 

转载于:https://www.cnblogs.com/JSZX11556/p/4717656.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值