离散上机实验四

补图

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic

Problem Description

题目给出一个无向图,求该无向图关于完全图的相对补图,并求该补图的最大度和最小度。方便起见,用邻接矩阵表示该无向图。无向图的节点数不少于2并且不超过500.

Input

多组输入,每组输入第一行是无向图中节点的数量即邻接矩阵的行列数n。接下来n行n列为该图的邻接矩阵。

Output

每组数据,首先输出n行n列表示补图的邻接矩阵。接下来一行两个用空格分隔的整数,分别代表补图的最大度和最小度。

Sample Input

4
0 0 1 1
0 0 0 1
1 0 0 0
1 1 0 0

Sample Output

0 1 0 0
1 0 1 0
0 1 0 1
0 0 1 0
2 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a[505][505],b[505][505];
int main()
{
    int n,i,j,gas,max,min;
    while(scanf("%d",&n)!=EOF)
    {
        max=0;
        min=505;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(i=0; i<n; i++)
        {
            for(j=0; j<n; j++)
            {
                scanf("%d",&a[i][j]);
                if(i!=j)
                {
                    if(a[i][j]==0)
                        b[i][j]=1;
                    else
                        b[i][j]=0;
                }
            }
        }
        for(i=0; i<n; i++)
        {
            gas=0;
            for(j=0; j<n; j++)
            {
                if(b[i][j]==1)gas++;
            }
            if(max<gas)max=gas;
            if(min>gas)min=gas;
        }
        for(i=0; i<n; i++)
        {
            for(j=0; j<n; j++)
            {
                if(j!=n-1)printf("%d ",b[i][j]);
                else printf("%d\n",b[i][j]);
            }
        }
        printf("%d %d\n",max,min);
    }
    return 0;
}

 

 

指定长度路径数

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic

Problem Description

题目给出一个有n个节点的有向图,求该有向图中长度为k的路径条数。方便起见,节点编号为1,2,…,n,用邻接矩阵表示该有向图。该有向图的节点数不少于2并且不超过500.

 

 

例如包含两个节点的有向图,图中有两条边1 → 2 ,2 → 1 。

长度为1的路径有两条:1 → 2 和 2 →1 ;

长度为2的路径有两条:1 → 2 → 1和2 → 1 → 2 ;

偷偷告诉你也无妨,其实这个图无论k取值多少 ( k > 0 ),长度为k的路径都是2条。

Input

多组输入,每组输入第一行是有向图中节点的数量即邻接矩阵的行列数n。接下来n行n列为该图的邻接矩阵。接下来一行是一个整数k.k小于30.

Output

输出一个整数,即为图中长度为k的路径的条数。

Sample Input

3
0 1 0
0 0 1
0 0 0
2

Sample Output

1

 

/*在有向图中,如果需要求vi到vj的长度为x的通路数,
只需要对矩阵A进行x次乘法即可,然后矩阵中a[i]][j]就是
vi到vj长度为x的通路数量,其中回路数量是a[i][i],然
后在计算机中怎么表示呢,求矩阵的n次幂需要3个数组,
一个作为a的x次幂的空白矩阵,另外两个一个存原来的矩阵即A本身
,另外一个矩阵存上一次幂的矩阵,这两个矩阵再存到空白矩
阵去,反复这样可以求出A的x次幂的矩阵*/
//以上是其他博主经验
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int n;
int ia[1105][1105];
int image[1005][1005];
int b[1005][1005];
int main()
{
    int i,j,o,k;
    while(scanf("%d",&n)!=EOF)
    {
        memset(image,0,sizeof(image));
        memset(b,0,sizeof(b));
        for(i=1; i<=n; i++)
        {
            for( j=1; j<=n; j++)
            {
                scanf("%d",&image[i][j]);
            }
        }
        for( i=1; i<=n; i++)
        {
            for( j=1; j<=n; j++)
            {
                ia[i][j]=image[i][j];
            }
        }
        int q;
        scanf("%d",&q);
        int count=0;
        for( o=2; o<=q; o++)
        {
            for( i=1; i<=n; i++)
            {
                for( j=1; j<=n; j++)
                {
                    for( k=1; k<=n; k++)
                    {
                        b[i][j]+=ia[i][k]*image[k][j];
                    }
                }
            }
            for( i=1; i<=n; i++)
            {
                for( j=1; j<=n; j++)
                    image[i][j]=b[i][j];
            }
            if(o!=q)
                memset(b,0,sizeof(b));

        }
        for( i=1; i<=n; i++)
        {
            for( j=1; j<=n; j++)
            {
                if(b[i][j])
                    count+=b[i][j];
            }
        }
        printf("%d\n",count);
    }
    return 0;
}

建图

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic

Problem Description

编程使得程序可以接受一个图的点边作为输入,然后显示出这个图。

Input

多组测试数据,对于每组测试数据,第一行输入正整数n(1 <= n <= 1000)和m,之后m行输入正整数x、y,表示在点x和点y之间存在有向边相连。

Output

对于每组测试数据,输出图的关系矩阵。

Sample Input

4 5
1 1
2 2
2 4
3 3
4 4

Sample Output

1 0 0 0
0 1 0 1
0 0 1 0
0 0 0 1
#include <stdio.h>
#include <string.h>
int main()
{
    int m,i,g,j,a1,a2;
    int a[1001][1001];
    while (scanf("%d%d",&m,&g)!=EOF)
    {
        memset(a,0,sizeof(a));
        for (i=1;i<=g;i++)
        {
            scanf("%d%d",&a1,&a2);
            a[a1][a2]=1;
        }
        for (i=1;i<=m;i++)
        {
            for (j=1;j<=m;j++)
            {
                if (j==1)printf("%d",a[i][j]);
                else printf(" %d",a[i][j]);
            }
            printf("\n");
        }
    }
    return 0;
}


/***************************************************
User name: 
Result: Accepted
Take time: 132ms
Take Memory: 2020KB
Submit time: 2019-06-06 10:30:32
****************************************************/

 

最小生成树

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic

Problem Description

在一个无向图中,求最小生成树。

Input

多组测试数据,对于每组测试数据,第1行输入正整数n(1 <= n <= 1000)、m,表示n个顶点(编号从1开始)和m条边。之后m行每行输入u(1 <= u <= n)、v(1 <= v <= n)、w(1 <= w <= 100),表示在顶点u和顶点v之间存在无向边,且权值为w。

Output

对于每组测试数据,若存在最小生成树则输出最小生成树的权值和,若不存在最小生成树则输出-1。

Sample Input

3 7
1 2 19
2 3 11
3 1 7
1 3 5
2 3 89
3 1 91
1 2 32

Sample Output

16
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define INF 0x3f3f3f3f
int n,m;
int mp[1100][1100],dis[1100],vis[1100];
int sum;
void f(int s)
{
    int i,j;
    for(i=1;i<=n;i++)
    {
        dis[i]=mp[s][i];
        vis[i]=0;
    }
    dis[s]=0;
    vis[s]=1;
    for(i=1;i<=n-1;i++)
    {
        int minn=INF;
        int u;
        for(j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]<minn)
            {
                minn=dis[j];
                u=j;
            }
        }
        if(minn==INF)
        {
         printf("-1\n");
         return ;
        }
        vis[u]=1;
        sum+=minn;
        for(j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]>mp[u][j])
            {
                dis[j]=mp[u][j];
            }
        }
    }
    printf("%d\n",sum);
}
int main ()
{
    int i,j,u,v,w;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(i==j)
                    mp[i][j]=0;
                else
                    mp[i][j]=INF;
            }
        }
        while(m--)
        {
            scanf("%d%d%d",&u,&v,&w);
            if(mp[u][v]>w)
            {
                mp[u][v]=mp[v][u]=w;
            }
        }
        sum=0;
        f(1);

    }
    return 0;
}


/***************************************************
User name: 
Result: Accepted
Take time: 84ms
Take Memory: 2420KB
Submit time: 2019-06-20 10:13:01
****************************************************/

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值