Problem Address:http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1308
Problem Address:http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1307
先做的是1308连接电脑1。
其实思路很简单,以至于自己都不太相信。对于后面给的那些连接都可以忽略。因为若要使网线数最少,n台电脑则需要n-1根网线。剩下的就是多余的。所以判断拥有的网线数和实际使用的网线数就可以直接得出答案。
之后到了1307,这道题不同的是不能改变已有的连接。所以只要求出连通量的个数就可以了。对于x个连通量,只需要x-1跳网线就可以把所有电脑连接起来。
最近在看图算法,所以试了一下,用邻接表dfs生成数并计算连通量个数。
DEBUG一下之后submit一次就AC了。
哈哈~
没想到第一次写求连通量个数这么轻松就过了。
不过还是要继续努力的!
下面贴代码:
ZJUT1308:
#include <iostream>
using namespace std;
int main()
{
int n,m,i,x,y;
while(scanf("%d %d", &n, &m)!=EOF)
{
if (n==0 && m==0) break;
for (i=0; i<m; i++) scanf("%d %d", &x, &y);//忽视连接数据
if (n-1-m<=0) printf("0/n");
else printf("%d/n", n-m-1);//直接计算
}
return 0;
}
ZJUT1307:
#include <iostream>
using namespace std;
struct note
{
int pos;
note *next;
};
note computer[205];
bool visited[205];
void dfs(int i)
{
note *temp;
temp = computer[i].next;
while(temp)
{
if (visited[temp->pos]==false)
{
visited[temp->pos] = true;
dfs(temp->pos);
}
temp = temp->next;
}
}
int main()
{
note *temp, *t;
int n,m,i,x,y,ct;
while(scanf("%d %d", &n, &m)!=EOF)
{
if (n==0 && m==0) break;
for (i=1; i<=n; i++) computer[i].next = NULL;
for (i=1; i<=n; i++) visited[i] = false;
for (i=0; i<m; i++)
{
scanf("%d %d", &x, &y);
temp = computer[x].next;
computer[x].next = (note*)malloc(sizeof(note));
computer[x].next->pos = y;
computer[x].next->next = temp;
temp = computer[y].next;
computer[y].next = (note*)malloc(sizeof(note));
computer[y].next->pos = x;
computer[y].next->next = temp;
}
ct = 0;
for (i=1; i<=n; i++)
{
if (visited[i]==false)
{
visited[i] = true;
ct++;
dfs(i);
}
}
printf("%d/n", ct-1);
for (i=1; i<=n; i++)
{
temp = computer[i].next;
if (temp!=NULL)
{
while(temp->next)
{
t = temp->next;
free(temp);
temp = t;
}
}
}
}
return 0;
}
p.s.要去吃饭的时候写出来AC掉,吃完饭回来写下解题报告。还是很满足的~