食物鏈
time limit:1000ms
memory limit:10000k
total submissions:55072
accepted:16149
description
動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b, b吃c,c吃a。
現有n個動物,以1-n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。
有人用兩種說法對這n個動物所構成的食物鏈關係進行描述:
第一種說法是"1 x y",表示x和y是同類。
第二種說法是"2 x y",表示x吃y。
此人對n個動物,用上述兩種說法,一句接一句地說出k句話,這k句話有的是真的,有的是假的。當一句話滿足下列三條之一時,這句話就是假話,否則就是真話。
1) 當前的話與前面的某些真的話衝突,就是假話;
2) 當前的話中x或y比n大,就是假話;
3) 當前的話表示x吃x,就是假話。
你的任務是根據給定的n(1 <= n <= 50,000)和k句話(0 <= k <= 100,000),輸出假話的總數。
input
第一行是兩個整數n和k,以乙個空格分隔。
以下k行每行是三個正整數 d,x,y,兩數之間用乙個空格隔開,其中d表示說法的種類。
若d=1,則表示x和y是同類。
若d=2,則表示x吃y。
output
只有乙個整數,表示假話的數目。
sample input
100 7sample output1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5
3source
noi 01
汗,在網上搜尋,看了半天的帶權並查集,看不懂,看了學妹的**看懂了,
有n個動物,對於每個動物k,設food[k]=k+i,food[k+i]=k+2i;food[k+2*i]=i;這樣就構成了一條迴圈食物鏈。
一共有三種動物,如果知道了兩個動物是一種那麼可以合併(並查集基本操作),並將他們對應的 food(**食者)和(捕食者)
合併。**上有注釋,很容易看懂:
#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#pragma comment(linker, "/stack:102400000,102400000")
#define pi 3.1415926535897932384626
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define for0(i,n) for(int i=0 ;i<(n) ;i++)
#define for1(i,n) for(int i=1 ;i<=(n) ;i++)
#define ford(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson num<<1,le,mid
#define rson num<<1|1,mid+1,ri
#define mid int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
using namespace std;
//const int inf= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int inf =0x3f3f3f3f;
const int maxn= 50000+20 ;
//const int maxm= ;
/*總結:
一共有n個動物,這裡虛擬出了2*n個,最後一共有3*n個,把每個動物x都虛擬出乙個相應的食物food[x]和捕食它的動物food[food[x]],
這樣對於x,虛擬本身出來的動物food[x]和food[food[x]]本身和x不產生矛盾,
會讓我們方便解題。
*/int pre[3*maxn],food[3*maxn];
int a[3],b[3];
int n,n,ans;//n動物種數、n虛擬的3*n種動物,ans 答案(假話數)
int find(int x)
void samegroup(bool same,int x,int y)//如果d==1
for(int i=0;i<3;i++)//如果兩者之前的食物鏈沒有合併過
}void different(bool same ,int x,int y)//如果d==2
//說x、y不是同種動物,但是x、y又一樣,是假話
if(same)//如果兩者之前的食物鏈合併過
for(int i=0;i<3;i++)
}void work()
//動物序號 > 大於動物個數,假話
a[0]=find(x);a[1]=find(food[a[0]] );a[2]=find(food[a[1]] );//取x所在食物鏈的****動物
b[0]=find(y);b[1]=find(food[b[0]] );b[2]=find(food[b[1]] );//取y所在食物鏈的****動物
bool same=false;
for(int j=0;j<3;j++)
}//如果same==1,那麼證明x、y所在的食物鏈已經合併過了,只需要判斷真假
if(rela==1) samegroup(same,x,y);//如果d==1
else different(same,x,y);//如果d==2
}void init()
}int main()
printf("%d\n",ans);
return 0;
}
POJ 1182 食物鏈 並查集
此題利用並查集解決。對於每只動物i建立3個元素i a,i b,i c,並用這3 n個元素建立並查集。1 i x表示 i屬於種類x 2 並查集你的每一組表示組內所有元素代表的情況同時發生或不發生。對於每一條資訊,只需要按照下列操作即可 1.第一種 x,y同類,合併x a和y a x b和y b x c...
POJ 1182 食物鏈 (並查集)
食物鏈time limit 1000ms memory limit 10000k total submissions 48713 accepted 14202 description 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n編...
POJ 1182 食物鏈(並查集)
description 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。有人用兩種說法對這n個動物所構成的食物鏈關係進行描述 第一種說法是 1 x y 表示x和y是...