| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
Java30题~~ 现在都习惯用Scanner类了,很方便,但就像C++里的cin一样,大量数据的时候就是比scanf慢得多。超时了n次,改用BufferReader类过了,把代码贴出来:
package poj1182;
import java.io.*;
public class Main {
static node[] p;
public static void main(String[] args) throws IOException {
java.io.BufferedReader input = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
//整行输入
String[] tm = input.readLine().split(" ");
//动物总数
int num = new Integer(tm[0]);
//描述语句数
int word = new Integer(tm[1]);
if(word == 0)
{
System.out.println(0);
System.exit(0);
}
//结点
p = new node[num+1];
//初始化
for(int i = 0; i <= num; i++)
{
p[i] = new node(i); //用构造函数初始化
}
//谎话数
int ans = 0;
while(word-- > 0)
{
//整行输入
String[] tmp = input.readLine().split(" ");
int d = new Integer(tmp[0]);
int x = new Integer(tmp[1]);
int y = new Integer(tmp[2]);
if(x > num || y > num||(d == 2 && x == y))
{
ans++;
continue;
}
int fx ;
if(p[x].dadNum == x )
fx = x;
else
fx = search(x);
int fy;
if(p[y].dadNum == y )
fy = y;
else
fy = search(y);
//在同一个集合中
if(fx == fy)
{
if(d == 1 && p[x].relation != p[y].relation)
ans++;
else if(d == 2 && (p[y].relation - p[x].relation +3)%3!=1)
ans++;
}
//不在同一个集合,合并 -- 即默认此句话为真
else
{
union(x, y, fx, fy, d);
}
}
System.out.println(ans);
}
//合并结点x、 y 所在集合
public static void union(int x, int y, int xDad, int yDad, int d)
{
//yDad对xDad的关系
int rltn = (d-1 + p[x].relation - p[y].relation +3 )%3;
//若x集合 较大,将 y集合并入x集合中
if(p[xDad].child >= p[yDad].child )
{
p[yDad].dadNum = xDad; //将 y 所在集合并入 x集合
p[yDad].relation = rltn; // ??
p[xDad].child += (p[yDad].child + 1);
}
else
{
p[xDad].dadNum = yDad;
p[xDad].relation = (3-rltn)%3;
p[yDad].child += (p[xDad].child + 1);
}
}
//查找结点x 所在集合,并进行路径压缩,返回该集合的根节点的编号
public static int search(int x)
{
if(p[x].dadNum == x)
return x;
int temp = p[x].dadNum;
p[x].dadNum = search(temp);
//更新压缩后与新父结点的关系
p[x].relation = (p[temp].relation + p[x].relation )%3; //??
return p[x].dadNum;
}
}
//结点包括四个信息:自己的编号、父结点的编号、与父结点的关系、所有子结点个数
class node
{
int dadNum;
int relation;
int child;
public node(int i)
{
dadNum = i;
relation = 0;
child = 0;
}
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator