刷题笔记day8

【PAT A1013】Battle Over Cities

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

const int maxv = 1005;
int vis[maxv] = {0};
int g[maxv][maxv];
int ccount;
int v;//每次去除的结点
int n,m,k;//城市数、路径数、查询数

void initg()
{
    int i,j;
    for(i=0;i<maxv;i++)
        for(j=0;j<maxv;j++)
            g[i][j] = 0;
}

void dfs(int nowv)
{
    if(nowv == v)
        return;
    vis[nowv] = 1;
    int i;
    for(i=1;i<=n;i++)
    {
        if(g[nowv][i]==1)
        {

            if(vis[i] == 0)
            {
                dfs(i);
               //printf("dfs(%d)\n",i);
            }
        }

    }
}

void DFSTrave()
{
    int i;
    for(i=1;i<=n;i++)
    {
        if(vis[i] == 0 && i!=v)
        {
            ccount++;
            dfs(i);
            //printf("dfs(%d)\n",i);
        }
    }
}

int main()
{

    scanf("%d%d%d",&n,&m,&k);

    int i;
    for(i=0;i<m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        g[a][b] = 1;
        g[b][a] = 1;
    }

    for(i=0;i<k;i++)
    {
        memset(vis,0,sizeof(vis));

        scanf("%d",&v);

        ccount = 0;

        DFSTrave();

        printf("%d\n",ccount-1);


    }
}

图的dfs遍历伪代码

//DFS遍历图
//伪代码:
DFS(u)
{
    vis[u] = true;
    for(从u出发能到达的所有顶点v)
    {
        if(vis[v] == false)
            DFS(v);
    }
}

DFSTrave(G)
{
    for(G的所有顶点u)
    {
        if(vis[u] == false)
            DFS(u);
    }
}

图的dfs遍历

const int maxv = 1000;
const int INF = INT_MAX;
//邻接矩阵版
int n,g[maxv][maxv];
bool vis[maxv] = {false};

void DFS(int u,int depth)
{
    vis[u] = true;
    for(int v=0;v<n;v++)
    {
        if(vis[v] == false && g[u][v]!=INF)
            DFS(v,depth+1);
    }
}

void DFSTrave()
{
    for(int u=0;u<n;u++)
    {
        if(vis[u] == false)
            DFS(u,1);
    }
}

//邻接表版
vector<int> adj[maxv];
int n;
bool vis[maxv] = {false};

void DFS(int u,int depth)
{
    vis[u] = true;
    
    for(int i=0;i<adj[u].size();i++)
    {
        int v = adj[u][i];
        if(vis[v] == false)
            DFS(v,depth+1);
    }
}

void DFSTrave()
{
    for(int u=0;u<n;u++)
    {
        if(vis[u] == false)
        {
            DFS(u,1);
        }
    }
}

【PAT A1034】 Head of a Gang

图的遍历。求连通块的总权值。

#include<iostream>
#include<map>
#include<string>
#include<cstdio>
using namespace std;

const int maxv = 2005;
int weight[maxv] = {0};
int g[maxv][maxv];
bool vis[maxv] = {false};

map<string,int> gang; //头目名、人数
map<string,int> string2int;
map<int,string> int2string;
int numperson = 0;
int n,k;

int change(string str)
{
    if(string2int.find(str)!=string2int.end())
    {
        return string2int[str];
    }
    else
    {
        string2int[str] = numperson;
        int2string[numperson] = str;
        return numperson++;
    }
}

void dfs(int v,int &head,int &total,int &nummember)
{
    vis[v] = true;
    nummember++;

    if(weight[v]>weight[head])
    {
        head = v;
    }

    int i;
    for(i=0;i<numperson;i++)
    {
        if(g[v][i]>0)
        {
            total += g[v][i];
            g[v][i] = g[i][v] = 0;
            if(vis[i] == false)
                dfs(i,head,total,nummember);
        }

    }
}

void DFSTrave()
{
    int i;
    for(i=0;i<numperson;i++)
    {
        if(vis[i] == false)
        {
            int head = i;
            int total = 0;
            int nummember = 0;
            dfs(i,head,total,nummember);
            //printf("dfs(%d,%d,%d,%d)\n",i,head,total,nummember);

            if(total > k && nummember > 2)
            {
                gang[int2string[head]] = nummember;
            }
        }
    }
}

int main()
{

    cin>>n>>k;

    int i,j;
    for(i=0;i<maxv;i++)
    {
        for(j=0;j<maxv;j++)
            g[i][j] = 0;
    }


    for(i=0;i<n;i++)
    {
        string str1,str2;
        int temp;
        cin>>str1>>str2>>temp;
        int id1 = change(str1);
        int id2 = change(str2);
        g[id1][id2] += temp;
        g[id2][id1] += temp;
        weight[id1] += temp;
        weight[id2] += temp;
    }
    //cout<<numperson<<endl;

    DFSTrave();

    cout<<gang.size()<<endl;
    map<string,int>::iterator it;
    for(it = gang.begin();it!=gang.end();it++)
    {
        cout<<it->first<<" "<<it->second<<endl;
    }

}

7-8 哈利·波特的考试

弗洛伊德算法——多源最短路

要注意中间节点k要放在循环的最外层。

坑点:二维数组初始赋值最好还是一个一个赋值。

#include<stdio.h>
#include<limits.h>
#include<stdlib.h>

//#define INT_MAX 1000000
int d[105][105]={INT_MAX};

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);

    if(n==1)
    {
        printf("0\n");
        return 0;
    }

    int i;
    int ii;
    for(i=1;i<=n;i++)
        for(ii=1;ii<=n;ii++)
        {
            if(i==ii)
                d[i][i] = 0;
            else
                d[i][ii] = INT_MAX;
        }


    for(i=1;i<=m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        scanf("%d",&d[a][b]);
        d[b][a] = d[a][b];
    }

    int k,j;

    for(k=1;k<=n;k++)
    {
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(d[i][k]!=INT_MAX && d[k][j]!=INT_MAX
                   && d[i][k]+d[k][j] < d[i][j])
                {
                    d[i][j] = d[i][k]+d[k][j] ;
                }
            }
        }
    }

    int index = 0;
    int ans = INT_MAX;//min
    int mm = 0;//max

    for(i=1;i<=n;i++)
    {
        mm = 0;
        for(j=1;j<=n;j++)
        {
            if(d[i][j]>=mm)
            {
                mm = d[i][j];
            }
        }

        if(mm<ans)
        {
            ans = mm;
            index = i;
        }
    }

    if(index == 0)
    {
        printf("0\n");
    }
    else
    {
        printf("%d %d\n",index,ans);
    }
}
posted @ 2020-03-15 01:23  yoyoyayababy  阅读(129)  评论(0编辑  收藏  举报