通信网络

超时,60

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector> 
#include<string>
#include<queue>
#include<map>
#include<stack>
using namespace std; 
const int maxn = 10005 ;
int d[1005][1005];         //d[i][j]=1  表示i部门知道j部门的存在并且j部门和所有d[x][i]=1的部门认识       
                        //d[i][j]=2  表示i部门和j部门相互认识,但是j部门无法认识i部门之前的部门 
bool vis[1005];            //vis[i]=true 表示具有所有d[x][i]=1的部门 
int main()
{
    int n,m; 
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        vis[i] = false; 
        for(int j=1;j<=n;j++)
        {
            if(i!=j)    d[i][j] = 0;
            else        d[i][j] = 1;
        }    
    }    
        
    for(int i=1;i<=m;i++)
    {
        int u,v; 
        scanf("%d %d",&u,&v);
        d[u][v] = 1;        //d[i][j]=1  表示i部门知道j部门的存在并且j部门和所有d[x][i]=1的部门认识       ,可传递 
        d[v][u]    = 2;        //d[i][j]=2  表示i部门和j部门相互认识,但是j部门无法认识i部门之前的部门       ,不可传递 
    }

    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            if(d[k][i]==1 && i!=k)    
            {        
                queue<int> q;
                q.push(k);    
                while(!q.empty())
                {
                    int temp = q.front();
                    q.pop();
                    for(int j=1;j<=n;j++)
                    {
                        if(d[j][temp] == 1 && j!=temp)
                        {
                            d[j][i] = 1;
                            if(d[i][j]!=1)
                                d[i][j] = 2; 
                            if(vis[j] == false)
                            {
                                vis[j] = true;
                                q.push(j);
                            }
                        } 
                    } 
                }
            }
        }
    }

    int ans = 0,i,j;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(d[i][j] == 0)
                break;
        }
        if(j==n+1)    ans++;
    }
    cout<<ans;
    return 0;
}

 

超时,80

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector> 
#include<string>
#include<queue>
#include<map>
#include<stack>
using namespace std; 
const int maxn = 10005 ;
int d[1005][1005];         //d[i][j]=1  表示i部门知道j部门的存在并且j部门和所有d[x][i]=1的部门认识       
                        //d[i][j]=2  表示i部门和j部门相互认识,但是j部门无法认识i部门之前的部门 
                        
bool vis[1005];            //vis[i]=true 表示具有所有d[x][i]=1的部门 
bool used[1005];        
struct EDGE
{
    int u,v;
}e[10005];        //节省时间,不必通过2个for循环寻找d[i][j]=1的边 

//通过e数组和vis 节省时间 

int main()
{
    int n,m; 
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        vis[i] = false;
        for(int j=1;j<=n;j++)
        {
            if(i!=j)    d[i][j] = 0;
            else        d[i][j] = 1;
        }        
    }                
        
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&e[i].u,&e[i].v);
        d[e[i].u][e[i].v] = 1;            //d[i][j]=1  表示i部门知道j部门的存在并且j部门和所有d[x][i]=1的部门认识       ,可传递 
        d[e[i].v][e[i].u] = 2;            //d[i][j]=2  表示i部门和j部门相互认识,但是j部门无法认识i部门之前的部门       ,不可传递 
    }
    
    int u,v;
    for(int k=1;k<=m;k++)
    {
        u = e[k].u;
        v = e[k].v;
         
        if(vis[u] == true)            //说明所有d[x][u]=1的点都已经找到,不需要回溯
        {
            for(int j=1;j<=n;j++)
            {
                if(d[j][u] == 1 && j!=u)
                {
                    d[j][v] = 1;
                    if(d[v][j]!=1)
                        d[v][j] = 2; 
                } 
            }
            continue; 
        } 
        
        for(int j=1;j<=n;j++)
            used[j]=false;        //false表示此次回溯中还没用过的点,防止双向回路死循环(用dfs,bfs特别注意), 
        
        
        queue<int> q;            //v向前回溯,寻找所有d[x][v]=1的点, 
        q.push(v);                //先寻找所有d[x][v]=1的点,再逐级往前推,bfs 
        used[v] = true; 
        while(!q.empty())                //错误点:死循环,有双向回路的时候 
        {
            int temp = q.front();        //第一次是v,第二次是使d[x][v]=1的x 
            q.pop();
            for(int j=1;j<=n;j++)
            {
                if(d[j][temp] == 1 && j!=temp)
                {
                    d[j][v] = 1;
                    if(d[v][j]!=1)
                        d[v][j] = 2; 
                    if(vis[temp] == true)        //说明所有d[x][temp]=1的点都已经找到,队列不需要继续添加temp前面的j 
                        continue;
                        
                    if(used[j] == true)            //顶点j已经参与回溯过 
                        continue;
                            
                    q.push(j);
                    used[j] = true;
                } 
            }        
        }
        vis[v] = true;        //通过回溯具有了所有d[x][v]=1的信息,x不一定与v直接连接 
        
    }
    int ans = 0,i,j;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(d[i][j] == 0)
                break;
        }
        if(j==n+1)    ans++;
    }
    cout<<ans;
    return 0;
}

编译错误

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector> 
#include<string>
#include<queue>
#include<map>
#include<stack>
using namespace std; 
int first[10005],next[10005]; 
int d[1005][1005];         //d[i][j]=1  表示i部门知道j部门的存在并且j部门和所有d[x][i]=1的部门认识 ,
                        //d[i][j]=2  表示i部门和j部门相互认识,但是j部门无法认识i部门之前的部门 
bool vis[1005];            //vis[i]=true 表示具有所有d[x][i]=1的部门 
bool used[1005];        
struct EDGE
{
    int u,v;
}e[10005];         

//通过e数组节省时间,不必通过2个for循环寻找d[i][j]=1的边
//通过vis数组节省时间,不必重复回溯 
//通过邻接表节省时间,u已知, 不必通过循环找到所有d[x][u]=1的点, 通过邻接表(反向连接) 
int main()
{
    int n,m; 
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        vis[i] = false;
        for(int j=1;j<=n;j++)
        {
            if(i!=j)    d[i][j] = 0;
            else        d[i][j] = 1;
        }        
    }                
    for(int i=1;i<=m;i++)
    {
        first[i] = -1;
        next[i] = -1;
    }
    
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&e[i].u,&e[i].v);
        d[e[i].u][e[i].v] = 1;            //d[i][j]=1  表示i部门知道j部门的存在并且j部门和所有d[x][i]=1的部门认识       ,可传递 
        d[e[i].v][e[i].u] = 2;            //d[i][j]=2  表示i部门和j部门相互认识,但是j部门无法认识i部门之前的部门       ,不可传递 
        
        next[i] = first[e[i].v];    //反向连接 ,2->1,3->1,e数组存储的还是正常的路径顺序,u=2,v=1 ;u=3,v=1 
        first[e[i].v] = i;            //但是通过邻接表连起来的顺序是 1->2->3,   
    }
    
    /*
    for(int i=1;i<=n;i++)
    {
        int num = first[i];
        while(num!=-1)
        {
            cout<<e[num].u<<" "<<e[num].v<<endl;
            num = next[num];
        }
        cout<<endl;
    }*/
    
    int u,v,j;
    for(int k=1;k<=m;k++)
    {
        u = e[k].u;
        v = e[k].v;
         
        if(vis[u] == true)            //说明所有d[x][u]=1的点都已经找到,不需要回溯,只需要使所有d[x][v]=1 
        {
            j = first[u];        //每个e[j]都是类似 x->->->u 这样的边        
            while(j!=-1)
            {
                d[e[j].u][v] = 1;
                if(d[v][e[j].u]!=1)
                    d[v][e[j].u] = 2; 
                j = next[j];
            }
            continue; 
        } 
        
        for(j=1;j<=n;j++)
            used[j]=false;        //false表示此次回溯中还没用过的点,防止双向回路死循环(用dfs,bfs特别注意), 
        
        
        queue<int> q;            
        q.push(v);                //寻找所有d[x][v]=1的点,x------>v
        used[v] = true;         //编号为v的顶点已经使用 
        
        while(!q.empty())                //错误点:死循环,有双向回路的时候 
        {
            int temp = q.front();         
            q.pop();
            j = first[temp];        
            while(j!=-1)
            {
                //找到所有d[x][temp]=1的点,令d[x][v] = 1; 
                //每个e[j] 都是 x->->temp 的边, 
                 
                d[e[j].u][v] = 1;
                if(d[v][e[j].u]!=1)
                    d[v][e[j].u] = 2; 
                
                if(vis[temp] == true)        //说明所有d[x][temp]=1的点都已经找到,队列不需要继续添加temp前面的j 
                {
                    j = next[j];
                    continue; 
                }    
                    
                if(used[e[j].u] == true)            //顶点e[j].u已经使用过 
                {
                    j = next[j];
                    continue; 
                }            
                q.push(e[j].u);
                used[e[j].u] = true;
                j = next[j];
            }
                    
        }
        vis[v] = true;        //通过回溯具有了所有d[x][v]=1的信息,x不一定与v直接连接 
        
    }
    int ans = 0,i;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(d[i][j] == 0)
                break;
        }
        if(j==n+1)    ans++;
    }
    cout<<ans;
    return 0;
}

 

posted @ 2019-03-15 13:51  萌新上路  阅读(138)  评论(0编辑  收藏  举报