2415. Cowntact Tracing

2415. Cowntact Tracing

(File IO): input: tracing.in output: tracing.out
Time limit: 1000 ms Space limit: 262144 KB Specific limit
Goto ProblemSet


Title description

Due to the outbreak of the highly contagious cattle infectious disease COWVID-19, Farmer John is very worried about the health of his cows (numbered 1 ... N). Recently, Farmer John tested all his cows and found that some cows tested positive for the disease. Using video surveillance in the cowshed, he was able to view the recent interactions between the cows and found that when the cows greeted each other, they would hold their hooves. Unfortunately, this is a way of spreading disease from one cow to another. Cow behavior. Farmer John aggregated a list with timestamps added, and each piece of data was in the form (t, x, y), indicating that at time t, cow x and cow y held their hooves. Farmer John also knows the following information:
(1) There is exactly one cow on his farm that initially carries disease (we call this cow "Patient Zero").
(2) Once a cow is infected, she will infect the disease in the next K holdings (may be holding the hoof multiple times with the same cow). After holding the hoof K times, she no longer transmitted diseases in her subsequent hoof (because she realized that she would infect the disease at this time, so she would wash her hoof carefully).
(3) Once a cow is infected, she will continue to be infected.
Unfortunately, Farmer John does not know which of his N cows is patient number zero, nor does he know the value of K! Based on his data, please help him narrow these unknowns. Ensure that there is at least one possible situation.

Input

The first line of input contains N (2≤N≤100) and T (1≤T≤250). The next line contains a string of length N, each character is 0 or 1, representing the current status of Farmer John's N cows-0 means a healthy cow, 1 means a diseased cow. Each of the following T lines contains a record in Farmer John ’s interaction list, consisting of three integers t, x, and y, where t is a positive integer time (t≤250) where an interaction occurs, and x and y are in the range 1 ... Different integers in N represent the two cows holding hooves at time t. At most only one interaction occurs at each moment.

Output

Output a line containing three integers x, y, and z, where x is the number of cows that may be patient number zero, y is the smallest possible K value consistent with the data, and z is the largest possible K value consistent with the data (if you pass the data The upper bound of K cannot be inferred, z outputs "Infinity"). Note that there may be K = 0.

Sample input

4 3
1100
7 1 2
5 2 3
6 2 4

Sample output

1 1 Infinity

prompt

The only thing that could be patient number zero is cow 1. For all K> 0, cow 1 infects cow 2 at time 7, while cow 3 and cow 4 are not infected.

The scalp is scratched, and after 48 hours of sleeplessness, finally ... do
n't just look at it, remember to like it!

Topics and ideas:
1. Sort the hoof data in ascending order according to time
2. Enumerate any cow; (count the number of patients with number zero)

3. Calculate the upper and lower bounds of k (detailed explanation later)
I made a superb pruning and disease-free cow, so I can't be patient zero! (If only a few cattle in the data are sick cattle, then the optimization is significant)

How to calculate the upper and lower bounds of k

Use l to represent the lower bound and r to be the upper bound;
use the g array to record the infection of the cow with the i-th cow as the zeroth patient, after holding the hoof k times;
find the lower bound:
we use a layer of circulation to simulate the change of k; ( for int k = 0 ~ T)
According to the title, each cow can only infect another within K times of holding the hoof, so we need to use an array wt to record the number of times the hoof has been held.

void qxj(int i) //求下界 
{
	for(int k=0;k<=T;k++)
	{
		memset(wt,0,sizeof(wt));
		memset(g,0,sizeof(g));
		g[i]=1; //零号病人 
		for(int j=1;j<=T;j++)
		{
			if(g[a[j].x]&&!g[a[j].y]&&wt[a[j].x]<k)      wt[a[j].x]++,g[a[j].y]=1; //x感染y
			else if(g[a[j].y]&&!g[a[j].x]&&wt[a[j].y]<k) wt[a[j].y]++,g[a[j].x]=1; //y感染x
			else if(g[a[j].x]&&g[a[j].y])                wt[a[j].x]++,wt[a[j].y]++; //两牛都已感染 
		}
		//cout<<check()<<endl;
		if(check()) 
		{
			flag=1; l=min(l,k); return; //符合他是零号病人,记录k的下界 
		}
	}
}

Seeking the upper bound: the
same reason, but there is a condition that there is no upper bound if there is no lower bound (because he cannot be patient number zero)
. How to judge the situation of "Infinity"?
So easy, if you meet the Tth time, obviously T-1, T-2 ... also meet, of course, we are talking about holding hands, not eating! , So the upper bound cannot be judged (Infinity)
can find a value less than T, which is obviously the upper bound (I'm in reverse order).
Of course you can also sort in ascending order, just take max!

void qsj(int i)  //求上界 
{
	if(!flag) return;
	for(int k=T;k>=0;k--)
	{
		memset(wt,0,sizeof(wt));
		memset(g,0,sizeof(g));
		g[i]=1; //零号病人 
		for(int j=1;j<=T;j++)
		{
			if(g[a[j].x]&&!g[a[j].y]&&wt[a[j].x]<k)      wt[a[j].x]++,g[a[j].y]=1; //x感染y
			else if(g[a[j].y]&&!g[a[j].x]&&wt[a[j].y]<k) wt[a[j].y]++,g[a[j].x]=1; //y感染x
			else if(g[a[j].x]&&g[a[j].y])                wt[a[j].x]++,wt[a[j].y]++; //两牛都已感染 
		}
		//cout<<check()<<endl;
		if(check()) 
		{
			r=max(r,k); return; //符合他是零号病人,记录k的上界 	
		}
	}
}

AC code

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e6;
struct node
{
	int t,x,y;
} a[300];
int n,T,f[210],g[210],wt[210],l=MAX,r,tot;
bool flag;
string s;
bool cmp(node x,node y) {return x.t<y.t;}
void input()
{
	scanf("%d%d",&n,&T);
	cin>>s;
	for(int i=0;i<n;i++) if(s[i]=='1') f[i+1]=1;
	for(int i=1;i<=T;i++) scanf("%d%d%d",&a[i].t,&a[i].x,&a[i].y);
	sort(a+1,a+1+T,cmp);
}
bool check()
{
	for(int i=1;i<=n;i++) if(f[i]!=g[i]) return 0;	
	return 1; 
}
void qxj(int i) //求下界 
{
	for(int k=0;k<=T;k++)
	{
		memset(wt,0,sizeof(wt));
		memset(g,0,sizeof(g));
		g[i]=1; //零号病人 
		for(int j=1;j<=T;j++)
		{
			if(g[a[j].x]&&!g[a[j].y]&&wt[a[j].x]<k)      wt[a[j].x]++,g[a[j].y]=1; //x感染y
			else if(g[a[j].y]&&!g[a[j].x]&&wt[a[j].y]<k) wt[a[j].y]++,g[a[j].x]=1; //y感染x
			else if(g[a[j].x]&&g[a[j].y])                wt[a[j].x]++,wt[a[j].y]++; //两牛都已感染 
		}
		//cout<<check()<<endl;
		if(check()) 
		{
			flag=1; l=min(l,k); return; //符合他是零号病人,记录k的下界 
		}
	}
}
void qsj(int i)  //求上界 
{
	if(!flag) return;
	for(int k=T;k>=0;k--)
	{
		memset(wt,0,sizeof(wt));
		memset(g,0,sizeof(g));
		g[i]=1; //零号病人 
		for(int j=1;j<=T;j++)
		{
			if(g[a[j].x]&&!g[a[j].y]&&wt[a[j].x]<k)      wt[a[j].x]++,g[a[j].y]=1; //x感染y
			else if(g[a[j].y]&&!g[a[j].x]&&wt[a[j].y]<k) wt[a[j].y]++,g[a[j].x]=1; //y感染x
			else if(g[a[j].x]&&g[a[j].y])                wt[a[j].x]++,wt[a[j].y]++; //两牛都已感染 
		}
		//cout<<check()<<endl;
		if(check()) 
		{
			r=max(r,k); return; //符合他是零号病人,记录k的上界 	
		}
	}
}
void work()
{
	for(int i=1;i<=n;i++)
	{
		flag=0;
		if(!f[i]) continue;  //没病的牛就不可能是零号病人 
		qxj(i);
		qsj(i);
		if(flag) tot++;//符合条件,零号病人加一 	
	}
}
int main()
{
	//fre(tracing);
	input();
	work();
	printf("%d %d ",tot,l);
	if(r==T) printf("Infinity");
	else printf("%d",r); 
	return 0;
}
Published 130 original articles · won 93 · views 6799

Guess you like

Origin blog.csdn.net/bigwinner888/article/details/105455819