SSL_2119【电子眼】

电子眼

题目

中山市石一个环境优美、气候宜人的小城市。因为城市的交通并不繁忙,市内的道路网很稀疏。准确地说,中山市有N-1条马路和N个路口,每条马路连接两个路口,每两个路口之间最多只有一条马路。作为一条交通网络,显然每两个路口之间都是可达的。为了更好地管理中山市的交通,市长决定在一些路口加装电子眼,用来随时监视路面情况。这些装在路口的电子眼能够监视所有连接到这个路口的马路。现在市长想知道最少需要在多少个路口安装电子眼才能监视所有的马路。市长已经把所有的路口都编上了1~N的号码。
给你中山市的地图,你能帮忙吗?

输入

输入文件traffic.in的第1行包括一个数字N(1<=N<=100000),表示中山市的路口数。接下来N-1行,每行两个数字x_i和y_i,用来描述N-1条路所连接的两个路口的编号。

输入

输出最少需要安装电子眼的数量。

Sample Input

3
1 2
1 3

Sample Output

1

解题思路

利用邻接表,定义结构体node,内含x作为链首,y作为链尾,next让所有以i为链首的边连成一条链,外面再定义一个head数组,代表每条链首对应的链的起始位置
这道题最妙的是,题目中N<=100000,但数组设200000能A,100001就会爆
令人无奈的数据

#include
#include
#include 
using namespace std;
long long n,x1,y1,tot,head[200001],c[200001][2],b[200001];
struct node
{
 long long x,y,next;
}a[200001];
void add(int x,int y)
{
 tot++;
 a[tot].x=x;
 a[tot].y=y;
 a[tot].next=head[x];
 head[x]=tot;
}
void dp(int dep)
{
 c[dep][1]=1; 
 c[dep][0]=0;
 b[dep]=1;
 for(int i=head[dep];i;i=a[i].next)
 {
  if(b[a[i].y]==1)continue;
  b[a[i].y]=1;
  dp(a[i].y);
  c[dep][0]=c[dep][0]+c[a[i].y][1];//该点放电子眼
  c[dep][1]=min(c[a[i].y][0],c[a[i].y][1])+c[dep][1];//该点不放电子眼,动态转移方程
 }
}
int main()
{
 scanf("%lld",&n);
 for(int i=1;i<=n-1;i++)
 {
  scanf("%lld%lld",&x1,&y1);
  add(x1,y1);
  add(y1,x1);
 }
 dp(1);
 printf("%d",min(c[1][0],c[1][1]));
}

你可能感兴趣的:(动态规划,c++,链表)