2009年11月21日 星期六

TIOJ 1256 砲打皮皮4 [Graph]

poao899    1900K    166MS    G++     1.72K     2009-11-19 23:06:02                        .

好慚愧QQ


這題只是複製TIOJ 1137 4.收費站設置問題的code當初只想用分帳玩一下開錯就AC了


蚯蚓:不是很明顯是AP點嗎

//*********************************

#include<stdio.h>
#include<algorithm>
#define MAX 200200
#define MAXV 10010
int getint(){
int g=0,c=getchar();
while(c==10||c==32||c==9)c=getchar();
while(c>='0'&&c<='9'){
g=g*10+c-48;
c=getchar();
}
return g;
}
struct Edge{
int j;
Edge *next;
}E[MAX],*V[MAXV];
int edgeCnt,APCnt;
int dateBack[MAXV];
int AP[MAXV],ttime;
int visited[MAXV];
int t,n,m,a,b;
void setEdge(int i,int j){
Edge *p,*now;
p=V[i];
V[i]=&E[++edgeCnt];
E[edgeCnt].j=j;
E[edgeCnt].next=p;
p=V[j];
V[j]=&E[++edgeCnt];
E[edgeCnt].j=i;
E[edgeCnt].next=p;
}
int FindAP(int now,int depth){
Edge *p=V[now];
int next,count=0;
bool isAP=0;
visited[now]=++ttime;
dateBack[now]=2147483647;
while(p!=NULL){
next=p->j;
if(!visited[next]){
count++;
int son=FindAP(next,depth+1);
if(son>=visited[now]){
dateBack[now]=son;
if(depth){
isAP=1;
}
}
dateBack[now]<?=son;
}
else{
dateBack[now]<?=visited[next];
}
p=p->next;
}
if(depth==0&&count>1 || isAP){
AP[APCnt++]=now;
}
return dateBack[now];
}
int caseCnt;
main(){
while(scanf("%d%d",&n,&m),n+m){
//Initialize
for(int i=0;i<MAXV;i++){
visited[i]=0;
V[i]=NULL;
}
edgeCnt=-1;APCnt=0;ttime=0;
//Construct a graph
for(int i=0;i<m;i++){
a=getint();
b=getint();
setEdge(a,b);
}
//Find AP
for(int i=1;i<=n;i++)
if(!visited[i])
FindAP(i,0);
//Output
std::sort(AP,AP+APCnt);
printf("Case #%d:",++caseCnt);
printf("%d ",APCnt);
if(!APCnt)puts("0");
for(int i=0;i<APCnt;i++,putchar(i==APCnt?'\n':32)){
printf("%d",AP[i]);
}
}
}


TIOJ 1432 骨牌遊戲 [Binary Search]

poao899    4K    15MS    G++     0.53K     2009-11-19 22:55:22                                 .

純粹為了練coding速度(咦

對答案二分搜。

//***********************

#include<stdio.h>
int n,w,s[1000000],val;
bool test(int max){
int cost=0,sum=0;
for(int i=0;i<n;i++){
sum+=s[i];
if(sum>max){
sum=s[i];
cost++;
if(cost>w)return 0;
}
}
return 1;
}
main(){
while(scanf("%d%d",&n,&w),n+w){
int l=0,r=0;
for(int i=0;i<n;i++){
scanf("%d",s+i);
if(s[i]>l)l=s[i];
r+=s[i];
}
while(l!=r){
int mid=(l+r)/2;
if(!test(mid))
l=mid+1;
else r=mid;
}
printf("%d\n",l);
}
}

TIOJ 1241 倍因道 Factor and Points [Sieve...?]

poao899    -4K    61MS    G++     0.44K     2009-11-19 17:11:34                              .

還是應該算Greedy(咦


Greedy檢查每個數適合當因數還是倍數

//************************
#include<stdio.h>
#include<algorithm>
int fac[2001];
int n,t,total;
main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
total=0;
for(int i=0;i<2001;i++)
fac[i]=0;
for(int i=1;i<=n;i++){
int m=n/i-1;
if(m>fac[i])
for(int j=i+i;j<=n;j+=i)
fac[j]++;
else total+=fac[i];
}
printf("%d\n",total);
}
}

TIOJ 1582 A TRIVIAL physical problem

poao899    0K    150MS    G++     1.18K     2009-11-19 16:57:37                        .

排序大賽最陰險的一題(汗


超糟糕的輸入本來想練習scanf的不過最後還是gets()進來慢慢處理

//**********************

#include<stdio.h>
#include<algorithm>
struct mul{
int base,exp;
bool operator<(const mul &b)const{
return exp>b.exp||exp==b.exp&&base>b.base;
}
}Mu[1000];
int cnt;
void set(int b,int e){
mul *p=&Mu[cnt];
p->base=b;
p->exp=e;
}
char in[10000];
main(){
gets(in);
int base,exp,s;
for(int i=0;in[i];cnt++){
base=0;
exp=0;
s=1;
if(in[i]=='-'){s=-1;i++;}
if(in[i]=='+'){i++;}
if(in[i]=='x'){base=1;}
for(;in[i]!='x'&&in[i]!='-'&&in[i]!='+'&&in[i];i++){
base=base*10+in[i]-48;
}
base*=s;
if(in[i]==0)break;
if(in[i]!='x'){cnt--;continue;}
i++;
if(in[i]!='^'){set(base,1);continue;}
i++;
s=1;
if(in[i]=='-'){s=-1;i++;}
if(in[i]=='+')i++;
for(;in[i]!='-'&&in[i]!='+'&&in[i];i++){
exp=exp*10+in[i]-48;
}
exp*=s;
//printf("<base%d exp%d>\n",base,exp);
if(!exp){cnt--;continue;}
set(base,exp);
}
if(!cnt)putchar('0');
else{
std::sort(Mu,Mu+cnt);
for(int i=0;i<cnt;i++){
int b=Mu[i].base;
int e=Mu[i].exp;
if(b*e>0&&i)putchar('+');
printf("%d",b*e);
if(e-1!=0){
putchar('x');
if(e-1!=1){
putchar('^');
printf("%d",e-1);
}
}
}
}
puts("");
}


TIOJ 1584 Doraemon and Dorayaki [sort]

poao899    1452K    46MS    G++     1.07K     2009-11-19 11:26:57                         .


Manhattan Distance.[曼哈頓距離(?]


然後注意如果剛好0吃到也不行

(是要保留一點力氣吃嗎orz)


//***************************

#include<stdio.h>
#include<algorithm>
#define abs(x) ((x)>0?(x):-(x))
struct node{
int x,y;
int dis;
int dist(node &b){
return abs(x-b.x)+abs(y-b.y);
}
bool operator<(const node &b)const{
return dis<b.dis;
}
void set(int i,int j){
x=i;y=j;
}
}dora,yaki[1000010];
int h,w,hp,g,yakiCnt,c,t;
main(){
scanf("%d",&t);
while(t--){
yakiCnt=0;
scanf("%d%d%d%d\n",&h,&w,&hp,&g);
for(int i=0;i<h;i++){
for(int j=0;j<w;j++){
c=getchar();
switch(c){
case 'D':
dora.set(i,j);
break;
case 'e':
yaki[yakiCnt++].set(i,j);
break;
}
}
getchar();
}
for(int i=0;i<yakiCnt;i++)
yaki[i].dis=dora.dist(yaki[i]);

std::sort(yaki,yaki+yakiCnt);
int i;
for(i=0;i<yakiCnt;i++){
if(hp-yaki[i].dis>0){
hp-=yaki[i].dis;
hp+=g;
if(hp-yaki[i].dis>0)
hp-=yaki[i].dis;
else{
//printf("%d\n",i);
break;
}
}
else{
//printf("%d\n",i);
break;
}
}
printf("%d\n",i);
}
}


TIOJ 1581 KUKUKU Game [DFS]

poao899    -8K    150MS    G++     1.75K     2009-11-18 20:36:55                         .

總算不是排序了(咦

這題比TIOJ 1025 數獨問題 ( 96校內賽 prob 2 ) 還陰多了QQ

會有一開始不合法、甚至0~4以外的數字出現

雖然如果吃過RE不難想到xD

//*****************************

#include<stdio.h>
int sudo[4][4];
int cnt;
void dfs(int i,int j){
//printf("%d %d\n",i,j);
if(i==4){
cnt++;
if(cnt!=1)return;
for(int k=0;k<4;k++){
for(int l=0;l<4;l++)
putchar(sudo[k][l]+48);
puts("");
}
puts("");
return;
}
bool find=0;
for(;i<4;i++){
for(;j<4;j++){
//printf("%d %d:%d\n",i,j,sudo[i][j]);
if(sudo[i][j]==0){
find=1;
break;
}
}
if(find)break;
j=0;
}
if(i==4){
dfs(i,j);
return;
}
bool used[5]={};
for(int k=0;k<4;k++){
used[sudo[k][j]]=1;
used[sudo[i][k]]=1;
}
for(int k=0;k<2;k++)
for(int l=0;l<2;l++)
used[sudo[k+i/2*2][l+j/2*2]]=1;
for(int k=1;k<5;k++){
//printf("%d %d:%d\n",i,j,k);
if(!used[k]){
//printf("%d %d:%d\n",i,j,k);
sudo[i][j]=k;
dfs(i,j);
}
}
sudo[i][j]=0;
}
main(){
for(int i=0;i<4;i++)
for(int j=0;j<4;j++){
scanf("%d",&sudo[i][j]);
if(sudo[i][j]>4||sudo[i][j]<0){
puts("I can not solve!!");
return 0;
}
}
bool used[5]={};
for(int i=0;i<4;i++){
for(int j=0;j<5;j++)used[j]=0;
for(int j=0;j<4;j++){
int c=sudo[i][j];
if(c&&used[c]){
puts("I can not solve!!");
return 0;
}
used[c]=1;
}
for(int j=0;j<5;j++)used[j]=0;
for(int j=0;j<4;j++){
int c=sudo[j][i];
if(c&&used[c]){
puts("I can not solve!!");
return 0;
}
used[c]=1;
}
}
for(int i=0;i<3;i+=2)
for(int j=0;j<3;j+=2){
for(int k=0;k<5;k++)used[k]=0;
for(int k=0;k<2;k++)
for(int l=0;l<2;l++){
int c=sudo[i+k][j+l];
if(c&&used[c]){
puts("I can not solve!!");
return 0;
}
used[c]=1;
}
}
dfs(0,0);
if(cnt)printf("We have %d way(s) to solve it!!\n",cnt);
else puts("I can not solve!!");
}


TIOJ 1583 SLIM KING [sort]

poao899    0K    182MS    G++     0.54K     2009-11-18 19:46:38                                 .


排序大賽pB  當然還是排序orz


反正只要排前十大那就Insertion比較快xD

//******************************

#include<stdio.h>
struct people{
char name[50];
int kg,cm;
double bmi;
void get(){
scanf("%s%d%d",name,&kg,&cm);
bmi=kg/((double)cm/100*(double)cm/100);
}
bool operator<(people &b){
return bmi<b.bmi;
}
}s[11],in,sw;
void puts(people &a){
puts(a.name);
//printf("%lf\n",a.bmi);
}
int n;
main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
in.get();
int j;
for(j=0;j<i&&j<11;j++){
if(s[j]<in){
sw=s[j];
s[j]=in;
in=sw;
}
}
s[j]=in;
}
for(int i=0;i<n&&i<10;i++)
puts(s[i]);
}


TIOJ 1585 Strange Sorting [sort]

poao899    1100K    46MS    G++     0.69K     2009-11-18 19:34:59                         .


排序大賽(誤)的最後一題


當然還是排序XD

//**********************

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define abs(a) (a>0?a:-a)
struct String{
char s[1100];
int len;
bool operator<(const String &b)const{
int min=len<b.len?len:b.len;
for(int i=0;i<min;i++){
if(s[i]!=b.s[i]){
int ra=-abs((s[i]-'a'-13));
int rb=-abs((b.s[i]-'a'-13));
return ra==rb?s[i]>b.s[i]:ra<rb;
}
}
if(len>b.len)return 0;
else return 1;
}
}S[1100];
int n;
main(){
//for(int i='a';i<='z';i++)
// printf("%c:%d\n",i,-abs((i-'a'-13)));
while(~scanf("%d",&n)){
getchar();
for(int i=0;i<n;i++){
gets(S[i].s);
S[i].len=strlen(S[i].s);
}
std::sort(S,S+n);
for(int i=0;i<n;i++)
puts(S[i].s);
}
}


TIOJ 1388 好強的史來姆 [DP]

poao899    28K    906MS    G++     0.52K     2009-11-18 09:09:04                                 .


跟正直DE(矩陣乘法最小花費)一樣類型

不過卡得頗緊|||


O(n^3)但是得壓常數Q


//***********************

//1388

#include<stdio.h>
long long dp[100][100];
int slime[100],n;
main(){
while(~scanf("%d",&n)){
for(int i=0;i<n;i++){
scanf("%d",slime+i);
for(int j=0;j<n;j++)
dp[i][j]=i==j?slime[i]:0;
}
for(int j=2;j<=n;j++)
for(int i=0;i+j<=n;i++){
int z=i+j-1;
for(int k=i;k<z;k++){
dp[i][z]>?=(j&1)?dp[i][k]*dp[k+1][z]:dp[i][k]+dp[k+1][z];
}
}
printf("%I64d\n",dp[0][n-1]);
}
}


TIOJ 1577 萬用字元(wildcard) ( 97北市賽 prob 2 )

poao899    -16K    1763MS    G++     0.48K     2009-11-17 11:16:49                         .

暴力會過,不過聽說可以Greedyˊˋ



//***************************
#include<stdio.h>
#include<string.h>
char find[30],in[30];
int flen,len;
bool chk(int i,int j){
//printf("%d %d \n",i,j);
if(i==flen&&j==len)return 1;
if(find[i]=='$'){
for(int k=j;k<=len;k++)
if(chk(i+1,k))
return 1;
return 0;
}
if(i==flen||j==len)return 0;
if(find[i]==in[j])
return chk(i+1,j+1);
return 0;
}
main(){
gets(find);
flen=strlen(find);
//printf("%d\n",flen);
while(gets(in)){
len=strlen(in);
if(chk(0,0))
puts(in);
}


TIOJ 1580 火星圍棋(go) ( 97北市賽 prob 5 )

poao899    44K    123MS    G++     2.31K     2009-11-17 10:51:02                                  .

當年噁爆的防破台題|||


凸包+Graph= =

被捏很大才寫得出來囧

//***************************

//go ( prob 5 ) Convex Hull + Floyd Warshall

#include<stdio.h>
#include<algorithm>
struct node{
int x,y;
bool outPoly;
bool operator<(const node &b)const{
return x==b.x?y<b.y:x<b.x;
}
}R[101],B[101];
int r,b;
struct edge{
int i,j;
edge *next;
}E[20000],*V[101];
int dis[101][101];
int edgeCnt;
int cross(node p,node a,node b){
a.x-=p.x;
a.y-=p.y;
b.x-=p.x;
b.y-=p.y;
//printf("cross %d\n",a.x*b.y - a.y*b.x);
return a.x*b.y - a.y*b.x;
}
void test(int a,int b){
//printf("%d %d\n",a,b);
for(int i=0;i<r;i++)
if(!R[i].outPoly)
if(cross(B[a],B[b],R[i])>0)
return;
edge *p=&E[edgeCnt++];
p->i=a;
p->j=b;
edge *q=V[a];
V[a]=p;
p->next=q;
dis[a][b]=1;
//printf("construct!!\n");
}
int stack[2000],top;
main(){
//Initialize
edgeCnt=0;
top=0;
for(int i=0;i<101;i++)
for(int j=0;j<101;j++)
dis[i][j]=100000;
//Input
scanf("%d%d",&b,&r);
for(int i=0;i<b;i++)
scanf("%d%d",&B[i].x,&B[i].y);
for(int i=0;i<r;i++){
scanf("%d%d",&R[i].x,&R[i].y);
R[i].outPoly=0;
}
//Convex Hull
std::sort(B,B+b);
stack[top++]=0;
stack[top]=1;
for(int i=2;i<b;i++){
while(top>0&&cross(B[stack[top-1]] , B[stack[top]] , B[i])>=0)
top--;
top++;
stack[top]=i;
}
int nTop=top;
for(int i=b-2;i>=0;i--){
while(top>nTop&&cross(B[stack[top-1]] , B[stack[top]] , B[i])>=0)
top--;
top++;
stack[top]=i;
}
//printf("nTop %d %d\n",nTop,top);
//for(int i=0;i<=top;i++)
//printf("%d %d\n",B[stack[i]].x,B[stack[i]].y);
//InPoly
int c=0;
for(int i=0;i<r;i++){
int dir=cross(B[stack[0]],B[stack[1]],R[i])>0?1:-1;
for(int j=2;j<=top;j++)
if(dir*(cross(B[stack[j-1]],B[stack[j]],R[i]))<0){
R[i].outPoly=1;
c++;
break;
}
//printf("%d %d Outpoly?%d\n",R[i].x,R[i].y,R[i].outPoly);
}
if(c==r){printf("%d\n",r*111);return 0;}
//Construct
for(int i=0;i<b;i++){
//printf("%d %d\n",B[i].x,B[i].y);
for(int j=0;j<b;j++)
if(i!=j)
test(i,j);
}
//Floyd Warshall
for(int k=0;k<b;k++)
for(int i=0;i<b;i++)
for(int j=0;j<b;j++)
if(dis[i][k]+dis[k][j]<dis[i][j])
dis[i][j]=dis[i][k]+dis[k][j];
//Output
int cnt=0,minCycle=100000;
for(int i=0;i<r;i++)
if(R[i].outPoly)
cnt++;
for(int i=0;i<b;i++)
minCycle<?=dis[i][i];
printf("%d\n",cnt*111+minCycle*20);

}


TIOJ 1578 調和三角(triangle) ( 97北市賽 prob 3 )

poao899    -8K    75MS    G++     0.23K     2009-11-17 09:05:00                                 .


學長:用Math竟然沒有比DP快|||


(1<=r,c<=28)


所以測資應該大一點取mod或大數(誤



//*******************************************

#include<stdio.h>
int dp(int r,int c){
if(r==c||c==1)return r;
else{
int a=dp(r-1,c-1);
int b=dp(r,c-1);
return (int)((long long)b*a/(b-a));
}
}
main(){
int r,c;
scanf("%d%d",&r,&c);
printf("%d\n",dp(r,c));
}

TIOJ 1576 餅乾製作(cookie) ( 97北市賽 prob 1 )

poao899    -8K    75MS    G++     0.28K     2009-11-17 08:59:09                                 .


暴力O(n)枚舉


聽說O(n^3)在北市賽會過orz?

#include<cstdio>
int a,b,c,d,s1,s2,s3,t,m1,m2,m3,max;
main(){
scanf("%d%d%d%d",&a,&b,&c,&d);
for(int i=0;i<=b;i++){
s2=i<?a;
s1=a-s2<?c;
s3=b-s2<?d;
t=s1*80+s2*100+s3*60;
if(t>max){
m1=s1;m2=s2;m3=s3;max=t;
}
}
printf("%d %d %d\n%d\n",m1,m2,m3,max);
}


TIOJ 1212 圖論 之 最小圈測試

poao899    1124K    8531MS    G++     0.94K     2009-11-17 08:50:50                                     .


應該有很多方法可以加速不過先算了xD


Floyd-Warshall掃過去O(n^3)就過了囧


//***************************


#include<stdio.h>
#define INF 50000
#define MV 501
#define ME 250100
int getint(){
int g=0,c=getchar();
while(c=='\n'||c==32||c==9)c=getchar();
while(c>='0'&&c<='9'){
g=g*10+c-48;
c=getchar();
}
return g;
}
int n,m,dis[MV][MV],min;
struct edge{
int j;
edge *next;
}E[ME],*V[MV];
void set(edge *p){
int i=getint();
p->j=getint();
edge *q=V[i];
V[i]=p;
p->next=q;
dis[i][p->j]=1;
}
main(){
while(1){
n=getint();
m=getint();
if(!n&&!m)break;
//Initialize
min=INF;
for(int i=0;i<MV;i++)
for(int j=0;j<MV;j++)
dis[i][j]=INF;
//Construct
for(int i=0;i<m;i++)
set(E+i);
//Floyd Warshall
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(dis[i][k]+dis[k][j]<dis[i][j])
dis[i][j]=dis[i][k]+dis[k][j];
//Cycle
for(int i=1;i<=n;i++)
if(dis[i][i]<min)
min=dis[i][i];
if(min!=INF)printf("%d\n",min);
else puts("0");
}
}


2009年11月13日 星期五

TIOJ 1122 最大子矩陣 ( 93北市賽 prob 3 )

poao899    -8K    31MS    G++     0.76K     2009-11-14 01:02:26                                 .


很直觀的O(n^3)DP...

是說小乃:O(n^6)爆搜也會過啦



不過DP co起來美觀一點點ˊˇˋ


//****************************

//93 prob 3

#include<stdio.h>
int matrix[22][22];
int sum[22][22],pre,max,n;
main(){
    while(~scanf("%d%d",&n,&matrix[1][1])){
        max=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(j==1){
                    if(i!=1)matrix[i][j]=matrix[1][1]+i;
                }
                else{
                    matrix[i][j]=(matrix[i][j-1]*17)%103;
                    if((i+j)%2)matrix[i][j]=-matrix[i][j];
                }
                sum[i][j]=sum[i-1][j]+matrix[i][j];
            }
        }
        for(int top=0;top<n;top++){
            for(int but=top+1;but<=n;but++){
                pre=0;
                for(int i=1;i<=n;i++){
                    if(pre<0){
                        pre=sum[but][i]-sum[top][i];
                        max>?=pre;
                    }
                    else{
                        pre+=sum[but][i]-sum[top][i];
                        max>?=pre;
                    }
                }
            }
        }
        printf("%d\n",max);
    }
}


TIOJ 1025 數獨問題 ( 96校內賽 prob 2 )

poao899    -8K    122MS    G++     0.92K     2009-11-13 22:38:26                                   .



感謝小可魚>//////////<


唔暴力DFS也沒有特別剪枝


絕對是因為忘了數獨怎麼拼才取這種變數名稱(?

//*************************

#include<stdio.h>
int surwdkgo[9][9],cnt;
void dfs(int i,int j){
    int ni=i,nj=j;
    if(ni==8&&nj==8){
        cnt++;
        for(int p=0;p<9;p++)
            for(int q=0;q<9;q++,putchar(q==9?'\n':32))
                printf("%d",surwdkgo[p][q]);
        puts("");
        return;
    }
    bool can=0;
    for(;ni<9&&!can;ni++){
        for(;nj<9&&!can;nj++){
            if(surwdkgo[ni][nj]==0)can=1;
            if(can)break;
        }
        if(can)break;
        nj=0;
    }
    if(!can){
        dfs(8,8);
        return;
    }
    bool used[10]={0};
    for(int k=0;k<9;k++){
        used[surwdkgo[k][nj]]=1;
        used[surwdkgo[ni][k]]=1;
    }
    for(int p=0;p<3;p++)
        for(int q=0;q<3;q++)
            used[surwdkgo[p+(ni/3*3)][q+(nj/3*3)]]=1;
    for(int k=1;k<10;k++){
        if(!used[k]){
            surwdkgo[ni][nj]=k;
            dfs(ni,nj);
        }
    }
    surwdkgo[ni][nj]=0;
}
main(){
    for(int i=0;i<9;i++)
        for(int j=0;j<9;j++){
            if(scanf("%d",&surwdkgo[i][j])==EOF)return 0;
        }
    dfs(0,0);
    printf("there are a total of %d solution(s).\n",cnt);
}


TIOJ 1491 G.丁丁共和國 ( NPSC 2007 )

 poao899    580K    15MS    G++     1.41K     2009-11-13 15:45:31                                 .


字串處理 + 最遠距離點對


唔順便練一下map XD  比想像中的好用太多了orz



之前寫過兩次DFS這次改寫樹型DP


//******************************

//1491
//Tree DP + map

#include<stdio.h>
#include<map>
#include<string.h>
struct name{
    char n[200];
    bool operator<(const name &b)const{
        return strcmp(n,b.n)>0;
    }
}c1,c2;
struct edge{
    int i,j;
    edge *next;
}E[6000],*V[3000];
int eCnt;
void set(int i,int j){
    edge *p;
    E[eCnt].i=i;
    E[eCnt].j=j;
    p=V[i];
    V[i]=&E[eCnt];
    E[eCnt].next=p;
    eCnt++;
    E[eCnt].i=j;
    E[eCnt].j=i;
    p=V[j];
    V[j]=&E[eCnt];
    E[eCnt].next=p;
    eCnt++;
}
int DP[3000];
int k,n,cnt,maxLen;
bool visited[3000];
int treeDP(int now){
    visited[now]=1;
    if(!DP[now]){
        int max=0,max2=0,n;
        edge *p=V[now];
        while(p!=NULL){
            if(visited[p->j]==0){
                //printf("now%d son %d\n",now,p->j);
                n=treeDP(p->j)+1;
                if(n>max){
                    max2=max;
                    max=n;
                }
                else if(n>max2){
                    max2=n;
                }
            }
            p=p->next;
        }
        maxLen>?=max+max2;
        DP[now]=max;
        //printf("DP%d %d\n",now,DP[now]);
    }
    return DP[now];
}
main(){
    scanf("%d",&k);
    while(k--){
        //Initialize
        std::map<name,int> city;
        scanf("%d",&n);
        maxLen=0;
        for(int i=0;i<3000;i++){
            DP[i]=0;
            V[i]=NULL;
            visited[i]=0;
        }
        eCnt=0;
        cnt=1;
        //Input
        while(1){
            scanf("%s%s",c1.n,c2.n);
            if(!strcmp(c1.n,"=") && !strcmp(c2.n,"="))break;
            int n1=city[c1],n2=city[c2];
            if(n1==0)n1=city[c1]=cnt++;
            if(n2==0)n2=city[c2]=cnt++;
            set(n1,n2);
        }
        treeDP(1);
        printf("%d\n",maxLen);
    }
}


TIOJ 1107 繁複的二元樹

poao899    15672K    203MS    G++     0.62K     2009-11-13 14:42:42                                     .




唔卡特蘭數

不過不知道這個遞迴式怎麼證明

本來想寫矩陣乘法


是說重載運算子真的這麼慢嗎@@


//*****************************

//1107 Catalan Number

#include<stdio.h>
struct num{
    double real;
    int exp;
    num operator*(int x){
        num t=*this;
        t.real*=x;
        while(t.real>10){
            t.real/=10;
            t.exp++;
        }
        return t;
    }
    num operator/(int x){
        num t=*this;
        t.real/=x;
        while(t.real<1){
            t.real*=10;
            t.exp--;
        }
        return t;
    }
    void set(int x){
        real=x;
        while(real>10){
            real/=10;
            exp++;
        }
    }
}Cat[1000010];
int n;
main(){
    num *cat=Cat;
    cat[0].set(1);
    for(int i=1;i<1000010;i++){
        cat[i]=(cat[i-1]*(4*i-2))/(i+1);
    }
    while(scanf("%d",&n),n){
        printf("%.3lfE+%d\n",cat[n].real,cat[n].exp);
    }
}


2009年11月12日 星期四

TIOJ 1162 5.小氣又愛現的老薑

poao899    72K    31MS    G++    1.32K     2009-11-12 23:36:19                                        .


唔囧純粹MST

本來想要鍊map不過看起來挑錯題了囧


//********************************

//1162 MST + map

#include<stdio.h>
#include<algorithm>
char city[60][40];
struct road{
    char name[40];
    int i,j,len,order;
    bool use;
    void set(int o){
        order=o;
        scanf("%s%d%d%d",name,&i,&j,&len);
        use=0;
    }
    bool operator<(const road &b)const{
        return len==b.len?order<b.order:len<b.len;
    }
}E[3000];
bool cmp(road a,road b){
    return a.order<b.order;
}
int n,root[60],m,edgeAdded,total;
int find(int a){
    return a==root[a]?a:root[a]=find(root[a]);
}
main(){
    while(scanf("%d",&n),n){
        //Initialize
        for(int i=0;i<60;i++){
            root[i]=i;
        }
        edgeAdded=0;total=0;
        //Input CityName
        for(int i=0;i<n;i++)
            scanf("%s",city[i]);
        //Input Edge
        scanf("%d",&m);
        for(int i=0;i<m;i++)
            E[i].set(i);
        scanf("%*s");
        //MST
        std::sort(E,E+m);
        for(int i=0;i<m&&edgeAdded<n-1;i++){
            int ra=find(E[i].i),rb=find(E[i].j);
            if(ra!=rb){
                E[i].use=1;
                edgeAdded++;
                root[ra]=rb;
                total+=E[i].len;
            }
        }
        //Output
        int cnt=1;
        std::sort(E,E+m,cmp);
        for(int i=0;i<m;i++)
            if(E[i].use)
                printf("#%d Road is named %s, connect %s and %s,length=%d\n",cnt++,E[i].name,city[E[i].i<?E[i].j],city[E[i].i>?E[i].j],E[i].len);

        printf("Jiang will spend %d TMTdollars.\n",total*100);
    }
}


TIOJ 1384 抵抗異形軍

poao899    1548K    686MS    G++     0.66K     2009-11-12 15:24:01                                 .




題目敘述不太好懂Q











二維的LIS










不過二分搜竟然寫炸=口=




//******************

//1384

#include<stdio.h>
#include<algorithm>
struct ship{
int t,h;
bool operator<(const ship &b)const{
return t==b.t?h<b.h:t<b.t;
}
}S[100050],leng[100050];
int n;
main(){
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d%d",&S[i].t,&S[i].h);
std::sort(S,S+n);
int len=0;

for(int i=0;i<n;i++){
if(S[i].h >= leng[len].h){
len++;
leng[len]=S[i];
continue;
}
int l=0,r=len;
while(l!=r){
int mid=(l+r)/2;
if(leng[mid].h <= S[i].h)
l=mid+1;
else
r=mid;
}
leng[l]=S[i];
}
printf("%d\n",n-len);
}

TIOJ 1163 6.施工中的道路

poao899    1168K    155MS    G++    1.46K     2009-11-12 09:26:18                                        .


這題太帥了XD













MST + [                 ]...











唔反正就是很神奇的東西

//**************************

//1163

#include<stdio.h>
#include<algorithm>
#define MAXE 50002
#define MAXV 30002
struct edge{
int i,j,cost;
bool operator<(const edge &b)const{
return cost<b.cost;
}
}E[MAXE];
int rank[MAXV],root[MAXV],tmp[MAXV];
int v,e,q,st,ed,edgeUsed;
int visit[MAXV],toFaLen[MAXV];
int find(int a){
return a==root[a]?a:find(root[a]);
}
void unionByRank(int a,int b,int ra,int rb,int cost){
//Let rank[ra]<=rank[rb]
if(rank[ra]>rank[rb]){
unionByRank(b,a,rb,ra,cost);return;
}
toFaLen[ra]=cost>?toFaLen[b];
root[ra]=rb;
if(rank[ra]==rank[rb])
rank[rb]++;
}
main(){
//Initialize
for(int i=0;i<MAXV;i++){
rank[i]=1;
root[i]=i;
}
scanf("%d%d",&v,&e);
for(int i=0;i<e;i++)
scanf("%d%d%d",&E[i].i,&E[i].j,&E[i].cost);
//MST
std::sort(E,E+e);
for(int i=0;i<e&&edgeUsed<v-1;i++){
int a=E[i].i,b=E[i].j,ra=find(a),rb=find(b);
if(ra!=rb){
//printf("add %d %d:%d\n",E[i].i,E[i].j,E[i].cost);
edgeUsed++;
unionByRank(a,b,ra,rb,E[i].cost);
}
}
//Query
scanf("%d",&q);
for(int i=1;i<=q;i++){
scanf("%d%d",&st,&ed);
int max=0,j;
bool reach=0;
visit[st]=i;
for(j=st;root[j]!=j;j=root[j]){
visit[j]=i;
tmp[j]=max;
if(max<toFaLen[j])max=toFaLen[j];
}
visit[j]=i;
tmp[j]=max;
max=0;
for(j=ed;root[j]!=j;j=root[j]){
if(visit[j]==i){reach=1;break;}
if(max<toFaLen[j])max=toFaLen[j];
}
reach=reach||(visit[j]==i);
reach?printf("%d\n",max>?tmp[j]):puts("-1");
}
}


2009年11月11日 星期三

TIOJ 1327 最小格子生成樹-EXTREME ( TFcis10 留社考 )

poao899    1092K    234MS    G++     1.64K     2009-11-11 15:48:24                                            .

原來每條邊只能垂直或水平=口=
















蚯蚓:雖然貌似完全圖,不過實際只有2V條邊














//*******************************

#include<stdio.h>
#include<algorithm>
#define V 100005
#define sw(i,j) {tmp=i;i=j;j=tmp;}
int getint(){
    int g=0,c=getchar(),s=1;
    while(c==10||c==32)c=getchar();
    if(c=='-')s=-1,c=getchar();
    while(c>='0'&&c<='9'){
        g=g*10+c-48;
        c=getchar();
    }
    return g*s;
}
int root[V],tmp;
int find(int a){
    return a==root[a]?a:root[a]=find(root[a]);
}
struct point{
    int x,y,order;
    bool operator<(const point &b)const{
        return x==b.x?y<b.y:x<b.x;
    }
    void get(int i){
        x=getint();
        y=getint();
        order=i;
    }
}P[V];
struct edge{
    int i,j,len;
    bool operator<(const edge &b)const{
        return len<b.len;
    }
   
}E[V*3];
int n,t,edgeCnt,edgeUsed;
long long MSTCost;
void set(int i,int j,int len){
    edge *p=&E[edgeCnt++];
    p->i=i;
    p->j=j;
    p->len=len;
}
main(){
    t=getint();
    while(t--){
        //Initialize
        edgeCnt=edgeUsed=0;
        MSTCost=0;
        for(int i=0;i<V;i++)
            root[i]=i;
        //Input
        n=getint();
        for(int i=0;i<n;i++)
            P[i].get(i);
        //Sort & Build Edge
        std::sort(P,P+n);
        for(int i=1;i<n;i++){
            if(P[i].x==P[i-1].x){
                set(P[i].order,P[i-1].order,P[i].y-P[i-1].y);
            }
            sw(P[i-1].x,P[i-1].y);
        }
        sw(P[n-1].x,P[n-1].y);
        std::sort(P,P+n);
        for(int i=1;i<n;i++){
            if(P[i].x==P[i-1].x){
                set(P[i].order,P[i-1].order,P[i].y-P[i-1].y);
            }
        }
        //Kruskal
        std::sort(E,E+edgeCnt);
        for(int i=0;i<edgeCnt&&edgeUsed<n-1;i++){
            int ri=find(E[i].i);
            int rj=find(E[i].j);
            if(ri!=rj){
                edgeUsed++;
                MSTCost+=E[i].len;
                root[ri]=rj;
            }
        }
        printf("%I64d\n",MSTCost);
    }
}


TIOJ 1178 Convex Hull


poao899    992K    212MS    G++     0.98K     2009-11-11 15:03:21                                    .


知道是按x軸就莫名其妙好co(?


很平凡的凸包(?



//*****************************

//Convex Hull

#include<stdio.h>
#include<algo.h>
int getint(){
    int g=0,c=getchar(),s=1;
    while(c==10||c==32)c=getchar();
    if(c=='-')s=-1,c=getchar();
    while(c>='0'&&c<='9'){
        g=g*10+c-48;
        c=getchar();
    }
    return g*s;
}
struct point{
    int x,y;
    bool operator<(const point b)const{
        return x==b.x?y<b.y:x<b.x;
    }
    void get(){
        x=getint();
        y=getint();
    }
}P[100000],*stack[200002];
long long cross(point a,point b,point c){
    b.x-=a.x;
    b.y-=a.y;
    c.x-=a.x;
    c.y-=a.y;
    return (long long)b.x*c.y-(long long)b.y*c.x;
}
int top=1,n;
main(){
    n=getint();
    point *q=P;
    for(int i=0;i<n;i++,q++)
        q->get();
    sort(P,q);
    stack[top]=P;
    stack[++top]=P+1;
    for(int i=1;i<n;i++){
        while(top>1 && cross(*stack[top-1],*stack[top],P[i])>=0)
            top--;
        top++;
        stack[top]=&P[i];
    }

    int now=top;
    for(int i=n-2;i>=0;i--){
        while(top>now && cross(*stack[top-1],*stack[top],P[i])>=0)
            top--;
        top++;
        stack[top]=&P[i];
    }
    printf("%d\n",top-1);
}

TIOJ 1535 嘿!! Let&#39;s Go E-m-i-r-p!!

poao899    14360K    3858MS    G++     0.93K     2009-11-11 14:05:58                                     .




很奇怪

之前TLE得超無辜

結果寫完USACO 1.5 sprime莫名其妙就過了...






//**************************

//emirp

#include<stdio.h>
#include<math.h>
#define MAX 11293974
bool notPrime[MAX];
int prime[744648],pCnt;
int emirp[100000],eCnt,sqMax;
bool testPrime(int k){
int sqk=(int)sqrt(k);
for(int i=0;i<pCnt&&prime[i]<=sqk;i++)
if(k%prime[i]==0)
return 0;
return 1;
}
inline bool isPrime(int k){
if(k%2==0)return 0;
if(k<MAX)return !notPrime[k];
else return testPrime(k);
}
int t,n;
main(){
sqMax=(int)(sqrt(MAX));
int i;
for(i=3;i<=sqMax;i+=2)
if(!notPrime[i]){
prime[pCnt++]=i;
for(int j=i*i;j<=MAX;j+=i)
notPrime[j]=1;
}
for(;i<MAX;i+=2)
if(!notPrime[i])
prime[pCnt++]=i;
for(int j=0;j<pCnt;j++){
int k=0,p=prime[j];
if(p<10)continue;
while(p>0){
k=k*10+p%10;
p/=10;
}
if(k==prime[j])continue;
if(isPrime(k))
emirp[eCnt++]=prime[j];
}
//printf("%d %d\n",pCnt,eCnt);
scanf("%d",&t);
while(t--){
scanf("%d",&n);
printf("%d\n",emirp[n-1]);
}
}


TIOJ 1062 用餐地點(Lunch) ( 95北市賽 prob 4 )

poao899    -8K    121MS    G++    0.74K     2009-11-11 11:02:41                                                 .



測資<100

但是可以O(n^2)


被阿思學長捏到QQ














"如果改變輸入格式可以O(n)..."













//*************************


//95 prob 4

#include<stdio.h>
int nSum[100],mSum[100];
int dpN[100],dpM[100];
int n,m,t,minN,minM,nn,mm;
main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++){
            scanf("%d",&t);
            nSum[i]+=t;
            mSum[j]+=t;
        }
    for(int i=0;i<n;i++)
        dpN[0]+=nSum[i]*i;
    for(int i=1;i<n;i++)
        nSum[i]+=nSum[i-1];
    minN=dpN[0];nn=0;
    for(int i=1;i<n;i++){
        (dpN[i]=dpN[i-1]-nSum[n-1]+nSum[i-1]*2);
        if(minN>dpN[i]){
            minN=dpN[i];
            nn=i;
        }
    }
    for(int i=0;i<m;i++)
        dpM[0]+=mSum[i]*i;
    for(int i=1;i<m;i++)
        mSum[i]+=mSum[i-1];
    minM=dpM[0];mm=0;
    for(int i=1;i<m;i++){
        (dpM[i]=dpM[i-1]-mSum[m-1]+mSum[i-1]*2);
        if(minM>dpM[i]){
            minM=dpM[i];
            mm=i;
        }
    }
    printf("%d %d\n",nn+1,mm+1);
}


2009年11月10日 星期二

TIOJ 1063 最大矩形(Area) ( 95北市賽 prob 5 )

poao899    -8K    120MS    G++     0.75K     2009-11-10 22:18:00                                .

沒有一次AC真慚愧QQ

枚舉底 Stack 合計O(n^2)


//***************************

//95 prob5

#include<stdio.h>
int stack[202][2],top;
int rec[201];
int n,m;
int max;
main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        top=stack[0][0]=stack[0][1]=0;
        for(int j=1;j<=m;j++){
            char c=getchar();
            while(c==32||c==10)c=getchar();
            if(c=='0')rec[j]=0;
            else if(c=='1')rec[j]++;
            int startPop=j;
            while(rec[j]<stack[top][0]){
                max>?=(j-stack[top][1])*stack[top][0];
                startPop<?=stack[top][1];
                top--;
            }
            if(stack[top][0]!=rec[j]){
                top++;
                stack[top][0]=rec[j];
                stack[top][1]=startPop;
            }
        }
        while(~top){
            max>?=(m-stack[top][1]+1)*stack[top][0];
            top--;
        }
    }
    printf("%d\n",max);
}


TIOJ 1514 Problem D. 橫掃射擊場

poao899    7816K    968MS    G++     0.67K     2009-11-10 16:13:38                               .

說來慚愧是亂co的(汗

唔就是求互質個數

n(1-1/p1)(1-1/p2)...(1-1/pk)

化簡

不過沒化簡完成XD


//**********************************

//1514

#include<stdio.h>
#define MAX 1000003
unsigned long long PHI[MAX],n;
int getint(){
    int g=0,c=getchar();
    while(c==10||c==32||c==9)c=getchar();
    if(c=='-')return -1;
    while(c>='0'&&c<='9'){
        g=g*10+c-48;
        c=getchar();
    }
    return g;
}
main(){
    unsigned long long *phi=PHI;
    for(int i=1;i<MAX;i+=2){
        if(i==1)i++;
        if(phi[i]==0){
            long long j=(long long)i;
            for(;j<MAX;j+=i){
                if(!phi[j])
                    phi[j]=j;
                phi[j]=phi[j]/i*(i-1);
            }
            phi[i]=i-1;
        }
       
        if(i==2)i--;
    }
    for(int i=1;i<MAX;i++){
        //if(i<20)printf("%d %I64d\n",i,phi[i]);
        phi[i]+=phi[i-1];
    }
    while(~(n=getint()))
        n?printf("%I64u\n",phi[n]*2+3):puts("0");
}


TIOJ 1118 非常速配 ( 92北市賽prob 4 )

poao899    0K    31MS    G++     0.62K     2009-11-10 13:33:55                                                 .


唔LCS

不過每次都被LCS初始化表|||   像是TIOJ 1385 芳佳的打工(汗


//**************************************

//92 prob4

#include<stdio.h>
#include<string.h>
int dp[20][20];
char n1[20],n2[20];
main(){
 n1[0]=n2[0]=1;
 while(gets(n1+1)){
  gets(n2+1);
  int i,j;
  for(int i=0;i<=strlen(n1+1);i++)
   dp[i][0]=-3*i;
  for(int j=0;j<=strlen(n2+1);j++)
   dp[0][j]=-3*j;
  for(i=1;n1[i];i++)
   for(j=1;n2[j];j++){
    if(n1[i]==n2[j]){
     dp[i][j]=(dp[i-1][j-1]+10)>?(dp[i-1][j]-3)>?(dp[i][j-1]-3);
    }
    else{
     dp[i][j]=(dp[i-1][j-1]-5)>?(dp[i-1][j]-3)>?(dp[i][j-1]-3);
    }
   }
  printf("%.2lf%%\n",(double)dp[strlen(n1+1)][strlen(n2+1)]*10/strlen(n1+1));
 }
}


2009年11月7日 星期六

UVa 336 A Node Too Far

佛洛伊德為什麼會WA  QQ                                                                                                                    .


這樣會讓我對佛洛伊德產生陰影QQ


//UVa 336

#include<stdio.h>
int dist[31][31];
int count[31][32];
int convert[31],ccnt=1;
int n,cnt=1,i,j;
int find(int key){
    for(int i=0;i<ccnt;i++)
        if(key==convert[i])
            return i;
    return -1;
}
main(){
    freopen("UVa336.in","r",stdin);
    freopen("UVa336.out","w",stdout);
    while(scanf("%d",&n),n){
        //Initialize
        ccnt=1;
        for(int i=0;i<31;i++)
            for(int j=0;j<31;j++){
                dist[i][j]=i==j?0:20000;
                count[i][j]=0;
            }
        //Input
        while(n--){
            int i,j;
            scanf("%d%d",&i,&j);
            int fi=find(i),fj=find(j);
            if(fi==-1)convert[ccnt++]=i;
            if(fj==-1)convert[ccnt++]=j;
            fi=find(i);
            fj=find(j);
            dist[fi][fj]=dist[fj][fi]=1;
        }
        //Floyd-Warshall
        for(int k=1;k<ccnt;k++)
            for(int i=1;i<ccnt;i++)
                for(int j=1;j<ccnt;j++)
                    if(dist[i][k]+dist[k][j]<dist[i][j])
                        dist[i][j]=dist[i][k]+dist[k][j];
        //Count The Dist
        for(int i=1;i<ccnt;i++){
            for(int j=1;j<ccnt;j++){
                //printf("dist %d %d:%d\n",i,j,dist[i][j]);
                if(dist[i][j]<31)
                    count[i][dist[i][j]]++;
            }
            for(int j=1;j<31;j++)
                count[i][j]+=count[i][j-1];
        }
        //Output
        while(1){
            int i,j,fi;
            scanf("%d%d",&i,&j);
            if(i==j&&!j)break;
            if(j>30)j=30;
            fi=find(i);
            printf("Case %d: %d nodes not reachable from node %d with TTL = %d.\n",cnt++,ccnt-1-count[find(i)][j],i,j);
        }
    }
}


2009年11月6日 星期五

TIOJ 1020 F.Number Insertion

poao899    -8K    763MS    G++     0.66K     2009-11-06 15:20:51                                 .

唔沒什麼好說的


暴力,不用特別cut...

//*****************************

#include<stdio.h>
#define sw(a,b) {int tmp=a;a=b;b=tmp;}
int arr[50],best[50],n,cnt;
void dfs(int now){
if(now>n){
cnt++;
for(int i=0;i<now;i++){
if(arr[i]<best[i])return;
else if(arr[i]>best[i]){
for(int j=0;j<now;j++){
best[j]=arr[j];
}
}
}
return;
}
arr[now]=now;
for(int i=now-1;i>0;i--){
sw(arr[i],arr[i+1]);
if(arr[i]%(arr[i+1]+arr[i-1])==0){
dfs(now+1);
}
}
sw(arr[0],arr[1]);
for(int i=0;i<now;i++)
arr[i]=arr[i+1];
}
main(){
scanf("%d",&n);
if(!n)return 0;
arr[0]=0;arr[1]=1;
dfs(2);
printf("%d\n",cnt);
for(int i=0;i<=n;i++,putchar((i<=n)?32:'\n'))
printf("%d",best[i]);
}


TIOJ 1092 A.跳格子遊戲

poao899    540K    15MS    G++     1.11K     2009-11-06 14:37:27                                   .


題目:

給一個DAG 兩個玩家輪流從1向N走每個人每次走一步

誰先到終點就贏了。























解法:

先依該點結束時間戳記,

然後從戳記最小的開始,

檢查每個點能不能走到終點時保持奇數步(即 先手勝)







//**************************************

#include<stdio.h>
struct edge{
int j;
edge *next;
}E[100100],*V[10010];
int edgeCnt;
int stamp[10010],ttime,dis[10010];
bool visited[10010];
int n,e,a,b;
char name[2][10]={"Mimi","Moumou"},in[10];
bool first;
void set(int i,int j){
edge *p=V[i];
E[edgeCnt].j=j;
V[i]=&E[edgeCnt];
E[edgeCnt].next=p;
edgeCnt++;
}
void topoSort(int now){
visited[now]=1;
edge *p=V[now];
while(p!=NULL){
if(!visited[p->j]){
topoSort(p->j);
}
p=p->next;
}
stamp[ttime++]=now;
}
main(){
while(scanf("%d%d",&n,&e),n+e){
//Initialize
for(int i=0;i<10010;i++){
V[i]=NULL;
visited[i]=0;
}
ttime=0;
//Construct a graph
for(int i=0;i<e;i++){
scanf("%d%d",&a,&b);
set(a,b);
}
//Name
scanf("%s",in);
first = ((in[1]=='i')?0:1);
//Topological sort
topoSort(1);
//
for(int i=0;i<ttime;i++){
int now=stamp[i];
if(now==n)dis[now]=0;
else{
edge *p=V[now];
dis[now]=0;
while(p!=NULL){
if(dis[p->j]==0){
dis[now]=1;
break;
}
p=p->next;
}
}
}
//Output
puts(name[first!=dis[1]]);
}
}




TIOJ 1137 4.收費站設置問題

poao899    1892K    31MS    G++     1.70K     2009-11-06 10:27:53                                 .


AP點。


其實沒什麼好說的這題XD

只是我co的是假解(?


測資太弱了Q

#include<stdio.h>
#include<algorithm>
#define MAX 200200
#define MAXV 10010
int getint(){
int g=0,c=getchar();
while(c==10||c==32||c==9)c=getchar();
while(c>='0'&&c<='9'){
g=g*10+c-48;
c=getchar();
}
return g;
}
struct Edge{
int j;
Edge *next;
}E[MAX],*V[MAXV];
int edgeCnt,APCnt;
int dateBack[MAXV];
int AP[MAXV],ttime;
int visited[MAXV];
int t,n,m,a,b;
void setEdge(int i,int j){
Edge *p,*now;
p=V[i];
V[i]=&E[++edgeCnt];
E[edgeCnt].j=j;
E[edgeCnt].next=p;
p=V[j];
V[j]=&E[++edgeCnt];
E[edgeCnt].j=i;
E[edgeCnt].next=p;
}
int FindAP(int now,int depth){
//printf("%d\n",now);
Edge *p=V[now];
int next,count=0;
bool isAP=0;
visited[now]=++ttime;
dateBack[now]=2147483647;
while(p!=NULL){
next=p->j;
if(!visited[next]){
count++;
int son=FindAP(next,depth+1);
if(son>=visited[now]){
dateBack[now]=son;
if(depth){
isAP=1;
}
}
dateBack[now]<?=son;
}
else{
dateBack[now]<?=visited[next];
}
p=p->next;
}
if(depth==0&&count>1 || isAP){
AP[APCnt++]=now;
}
return dateBack[now];
}
main(){
t=getint();
while(t--){
//Initialize
for(int i=0;i<MAXV;i++){
visited[i]=0;
V[i]=NULL;
}
edgeCnt=-1;APCnt=0;ttime=0;
//Construct a graph
n=getint();
m=getint();
for(int i=0;i<m;i++){
a=getint();
b=getint();
setEdge(a,b);
}
//Find AP
for(int i=1;i<=n;i++)
if(!visited[i])
FindAP(i,0);
//Output
std::sort(AP,AP+APCnt);
printf("%d\n",APCnt);
if(!APCnt)puts("0");
for(int i=0;i<APCnt;i++,putchar(i==APCnt?'\n':32)){
printf("%d",AP[i]);
}
}
}


TIOJ 1451 八卦傳播系統

poao899    3516K    398MS    G++     1.29K     2009-11-06 08:55:02                                     .


唔嘎如果沒有長期被捏可能想不到Q

題目:

給一張有向圖,請問最少要多少個起點才能遍歷每個點。

v, e <= 100,000






















解法:

一直被捏是SCC但是詳細怎麼寫現在才弄出來

縮點之後就是DAG了

所以沒有入分支度的點就一定得當起點








//***************************************************

#include<stdio.h>
#define MAX 100100
int getint(){
int g=0,c=getchar();
while(c==10||c==32||c==9)c=getchar();
while(c>='0'&&c<='9'){
g=g*10+c-48;
c=getchar();
}
return g;
}
struct edge{
int j;
edge *next;
}E[MAX],Er[MAX],*V[MAX],*Vr[MAX];
int stamp[MAX],cnt;
bool visited[MAX];
int scc,belong[MAX],inscc;
bool noindeg;
int n,m,a,b;
void dfs(int start){
edge *p=V[start];
visited[start]=1;
while(p!=NULL){
if(!visited[p->j]){
dfs(p->j);
}
p=p->next;
}
stamp[cnt++]=start;
}
void dfsr(int start){
edge *p=Vr[start];
visited[start]=1;
belong[start]=inscc;
while(p!=NULL){
if(!visited[p->j]){
dfsr(p->j);
}
else if(belong[p->j]!=inscc){
noindeg=0;
}
p=p->next;
}
}
main(){
n=getint();
m=getint();
//construct a graph and a reverse graph
for(int i=0;i<m;i++){
a=getint();
b=getint();
E[i].j=b;
edge *p=V[a];
V[a]=&E[i];
E[i].next=p;

Er[i].j=a;
p=Vr[b];
Vr[b]=&Er[i];
Er[i].next=p;
}
//正的一次
for(int i=1;i<=n;i++)
if(!visited[i])
dfs(i);
for(int i=1;i<=n;i++)
visited[i]=0;
//反的一次
for(int i=n-1;i>=0;i--){
//printf("%d: %d\n",i,stamp[i]);
if(!visited[stamp[i]]){
++inscc;
noindeg=1;
dfsr(stamp[i]);
scc+=noindeg;
}
}
printf("%d\n",scc);
}


2009年11月3日 星期二

TIOJ 1084 一筆畫問題

poao899    184K    15MS    G++     1.43K     2009-11-03 22:40:43                              .


當我在co時我到底有沒有計畫我要co什麼

蚯蚓:你這樣可能寫不了大程式


另外不從1開始好糟糕Q

最近開始轉USACO  可能這裡放的題目會少一點XD

//*******************************

#include<stdio.h>
#include<algo.h>
struct edge{
    int j;
    bool use;
    edge *next,*topair;
    bool operator<(const edge &b)const{
        return j<b.j;
    }
}E[3000],*V[1000],tmp[1000];
int deg[1000];
int m;
int trace[3000];
int top,cnt;
void set(int i,int j){
    E[cnt].topair=&E[cnt+1];
    E[cnt].use=1;
    E[cnt].j=j;
    edge *p=V[i];
    V[i]=E+cnt;
    E[cnt].next=p;
    cnt++;
   
    E[cnt].topair=&E[cnt-1];
    E[cnt].use=1;
    E[cnt].j=i;
    p=V[j];
    V[j]=E+cnt;
    E[cnt].next=p;
    cnt++;
    deg[i]++;
    deg[j]++;
}
void dfs(int node){
    while(V[node]!=NULL){
        if(V[node]->use){
            V[node]->use = V[node]->topair->use = 0;
            int x=V[node]->j;
            V[node]=V[node]->next;
            dfs(x);
        }
        else
            V[node] = V[node]->next;
    }
    trace[top++]=node;
    return;
}
main(){
    while(scanf("%d",&m),m){
        top=0;
        cnt=0;
        for(int i=0;i<1000;i++){
            V[i]=NULL;
            deg[i]=0;
        }
        for(int i=0;i<m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            set(a,b);
        }
        int n;
        for(n=1;n<1000;n++){
            edge *p;
            int i;
            for(i=0,p=V[n];p!=NULL;p=p->next)
                tmp[i++]=*p;
            sort(tmp,tmp+i);
            for(i=0,p=V[n];p!=NULL;p=p->next){
                p->j=tmp[i].j;
                tmp[i].topair->topair=p;
                p->topair=tmp[i].topair;
                i++;
            }
        }
        int start=9999;
        for(int i=1;i<n;i++){
            if(deg[i]>0){
                start<?=i;
            }
            if(deg[i]%2){
                start=i;
                break;
            }
        }
        dfs(start);
        while(top)
            printf("%d\n",trace[--top]);
        puts("");
    }
}