1. 程式人生 > >P2835 刻錄光盤

P2835 刻錄光盤

head 我們 pop style string stream long -m 但是

洛谷—— P2835 刻錄光盤

題目描述

在JSOI2005夏令營快要結束的時候,很多營員提出來要把整個夏令營期間的資料刻錄成一張光盤給大家,以便大家回去後繼續學習。組委會覺得這個主意不錯!可是組委會一時沒有足夠的空光盤,沒法保證每個人都能拿到刻錄上資料的光盤,又來不及去買了,怎麽辦呢?!

組委會把這個難題交給了LHC,LHC分析了一下所有營員的地域關系,發現有些營員是一個城市的,其實他們只需要一張就可以了,因為一個人拿到光盤後,其他人可以帶著U盤之類的東西去拷貝啊!

可是,LHC調查後發現,由於種種原因,有些營員並不是那麽的合作,他們願意某一些人到他那兒拷貝資料,當然也可能不願意讓另外一些人到他那兒拷貝資料,這與我們JSOI宣揚的團隊合作精神格格不入!!!

現在假設總共有N個營員(2<=N<=200),每個營員的編號為1~N。LHC給每個人發了一張調查表,讓每個營員填上自己願意讓哪些人到他那兒拷貝資料。當然,如果A願意把資料拷貝給B,而B又願意把資料拷貝給C,則一旦A獲得了資料,則B,C都會獲得資料。

現在,請你編寫一個程序,根據回收上來的調查表,幫助LHC計算出組委會至少要刻錄多少張光盤,才能保證所有營員回去後都能得到夏令營資料?

輸入輸出格式

輸入格式:

先是一個數N,接下來的N行,分別表示各個營員願意把自己獲得的資料拷貝給其他哪些營員。即輸入數據的第i+1行表示第i個營員願意把資料拷貝給那些營員的編號,以一個0結束。如果一個營員不願意拷貝資料給任何人,則相應的行只有1個0,一行中的若幹數之間用一個空格隔開。

輸出格式:

一個正整數,表示最少要刻錄的光盤數。

輸入輸出樣例

輸入樣例#1:
5
2 3 4 0
4 5 0
0
0
1 0
輸出樣例#1:
1


代碼:
智障啊。。。。
技術分享

技術分享技術分享技術分享

mdzz用讀入優化做第六個點超時,不用讀入優化就過了,過了。。。。

#include<stack>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define
N 29999//在洛谷上交的時候,必須的大一點,不然RE
using namespace std; stack<int>s; struct Edge { int from,to,next; }edge[N]; bool vis[N]; int n,x,y,tot,sum,ans,tim; int in[N],dfn[N],low[N],head[N],belong[N]; void add(int x,int y) { tot++; edge[tot].to=y; edge[tot].next=head[x]; head[x]=tot; } int tarjan(int now) { dfn[now]=low[now]=++tim; vis[now]=true;s.push(now); int j; for(int i=head[now];i;i=edge[i].next) { j=edge[i].to; if(vis[j]) low[now]=min(dfn[j],low[now]); else if(!dfn[j]) tarjan(j),low[now]=min(low[now],low[j]); } if(low[now]==dfn[now]) { sum++; do { j=s.top(); s.pop(); vis[j]=0; belong[j]=sum; }while(j!=now); } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&x); while(x) { add(i,x); scanf("%d",&x); } } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=n;i++) { for(int j=head[i];j;j=edge[j].next) { y=edge[j].to; if(belong[i]!=belong[y]) in[belong[y]]=1; } } for(int i=1;i<=sum;i++) if(!in[i]) ans++; printf("%d",ans); return 0; }


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 2010
using namespace std;
bool vis[N];
int n,a,ans,sum,tat,top,tim;
int in[N],head[N],dfn[N],low[N],stack[N],col[N];
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9){if(ch==-) f=-1; ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0; ch=getchar();}
    return x*f;
}
struct Edge
{
    int from,next,to;
 }edge[N];
inline int add(int x,int y)
{
    tat++;
    edge[tat].to=y;
    edge[tat].next=head[x];
    head[x]=tat;
}
inline void tarjan(int now)
{
    dfn[now]=low[now]=++tim;
    stack[++top]=now;vis[now]=true;
    int t;
    for(int i=head[now];i;i=edge[i].next)
    {
        t=edge[i].to;
        if(vis[t]) low[now]=min(low[now],dfn[t]);
        else if(!dfn[t]) tarjan(t),low[now]=min(low[now],low[t]);
    }
    if(low[now]==dfn[now])
    {
        sum++;col[now]=sum;
        for(;stack[top]!=now;top--)
        {
            col[stack[top]]=sum;
            vis[stack[top]]=false;
        }
        vis[now]=false; top--;
    }
}
inline void shrink_point()
{
    for(int i=1;i<=n;i++)
     for(int j=head[i];j;j=edge[j].next)
      if(col[i]!=col[edge[j].to])
      { in[col[edge[j].to]]=1; } 
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
    {
        while(1)
        {
           a=read();
           if(a==0) break;
           add(i,a);
        }
    }
    for(int i=1;i<=n;i++)
     if(!dfn[i]) tarjan(i);
    shrink_point();
    for(int i=1;i<=sum;i++)
     if(in[i]==0) ans++;
    printf("%d",ans);
    return 0; 
}

錯誤:in[col[edge[j].to]]++;我最開始是這樣打的,但是這樣在codevs上最後一個點不過,改成in[col[edge[j].to]]=1就過了!!!!迷啊?!哪位大佬可以跟我說說。。。

但這樣在洛谷上不過,我們需要把數據範圍開大點。。。。(唉,在codevs上1000可以過,在洛谷上就必須開到30000。。。。。)

 

P2835 刻錄光盤