实验8 贪心算法实验二

实验8 贪心算法实验二
OJ练习
1. 畅通工程:http://acm.hdu.edu.cn/showproblem.php?pid=1232
2. Constructing Roads: http://acm.hdu.edu.cn/showproblem.php?pid=1102
3. Jungle Roads: http://acm.hdu.edu.cn/showproblem.php?pid=1301
4. 还是畅通工程: http://acm.hdu.edu.cn/showproblem.php?pid=1233
5. 小希的迷宫: http://acm.hdu.edu.cn/showproblem.php?pid=1272
6. A Bug’s Life: http://acm.hdu.edu.cn/showproblem.php?pid=1829
7*. Connect the Cities: http://acm.hdu.edu.cn/showproblem.php?pid=3371
8*. Transfer water: http://acm.hdu.edu.cn/showproblem.php?pid=4009
9*. Pseudoforest: http://acm.hdu.edu.cn/showproblem.php?pid=3367
10*. Farm Irrigation: http://acm.hdu.edu.cn/showproblem.php?pid=1198
11*. Eddy’s picture: http://acm.hdu.edu.cn/showproblem.php?pid=1162
12*. find the most comfortable road:
http://acm.hdu.edu.cn/showproblem.php?pid=1598
13*. Virtual Friends: http://acm.hdu.edu.cn/showproblem.php?pid=3172
14*. Hand in Hand: http://acm.hdu.edu.cn/showproblem.php?pid=3926
15*. Dragon Balls: http://acm.hdu.edu.cn/showproblem.php?pid=3635
16*. Is It A Tree?: http://acm.hdu.edu.cn/showproblem.php?pid=1325

实验内容
1. 使用Prim算法求图的最小生成树(MST)。
输入:顶点编号及边权重。例:
0 1 10
0 2 15
1 2 50
输出:最小生成树。例:
0 1 10
0 2 15
源代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define debug() puts("++++")
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a,b,sizeof(a))
#define sz size()
#define be begin()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
#define all 1,n,1
#define rep(i,n,x) for(int i=(x); i<(n); i++)
#define in freopen("in.in","r",stdin)
#define out freopen("out.out","w",stdout)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e18;
const int MAXN =  1e3 + 5;
const int maxm = 1e6 + 10;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int dx[] = {-1,1,0,0,1,1,-1,-1};
const int dy[] = {0,0,1,-1,1,-1,1,-1};
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int G[MAXN][MAXN];
int n,m;
void prim()
{
    int lowcost[MAXN],closest[MAXN],vis[MAXN];
    vis[1]=1;
    for(int i=2; i<=n; i++){
        lowcost[i]=G[1][i];
        closest[i]=1;
        vis[i]=0;
    }

    for(int i=1;iint Min = INF;
        int j=1;
        for(int k=1;k<=n;k++)
            if((!vis[k]) && lowcost[k]printf("%d %d %d\n",closest[j],j,lowcost[j]);
         vis[j]=1;
         for(int k=2;k<=n;k++){
             if(G[j][k] < lowcost[k] && !vis[k]){
                lowcost[k]=G[j][k];
                closest[k] = j;
             }
         }
    }
}
int main()
{
    int a,b,c;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            G[i][j] = INF;
        }
    }
    for(int i=1;i<=m;i++){
        cin>>a>>b>>c;
        G[a][b]=G[b][a]=c;
    }
    prim();
}
/*
3 3
1 2 10
1 3 15
2 3 50
1 2 10
1 3 15
*/

  1. 在某个城市中住着n个人,现在给定关于这n个人的m条信息(即某2个人认识)。假设所有认识的人一定属于同一个单位,请计算该城市有多少个单位?
    输入:第1行的第1个值表示总人数,第2个值表示总信息数;第2行开始为具体的认识关系信息。例:
    10 4
    2 3
    4 5
    4 8
    5 8
    输出:单位个数。例:
    7
    源代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define debug() puts("++++")
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a,b,sizeof(a))
#define sz size()
#define be begin()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
#define all 1,n,1
#define rep(i,n,x) for(int i=(x); i<(n); i++)
#define in freopen("in.in","r",stdin)
#define out freopen("out.out","w",stdout)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e18;
const int MAXN =  1e3 + 5;
const int maxm = 1e6 + 10;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int dx[] = {-1,1,0,0,1,1,-1,-1};
const int dy[] = {0,0,1,-1,1,-1,1,-1};
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/*
10 4
2 3
4 5
4 8
5 8

7
*/
int n,m;
int fa[maxm];
void init()
{
    for(int i=0;iint Find(int x)
{
    return fa[x]==x?fa[x]:Find(fa[x]);
}
void join(int x,int y)
{
    x=Find(x),y=Find(y);
    if(x!=y){
        fa[x]=y;
    }
}
int main()
{
    cin>>n>>m;
    init();
    for(int i=0;iint a,b;
        cin>>a>>b;
        join(a,b);
    }
    int cnt=0;
    for(int i=0;iif(fa[i]==i){
            cnt++;
        }
    }
    cout<
3. 如果一个社团中有一个学生疑似非典病人,那么该社团中所有学生都将被隔离。假定编号为0的学生疑似非典病人,统计将被隔离的学生总人数(包括编号为0的学生)。

输入:
第1行的第1个数字n表示学生总人数,第2个数字m表示社团个数;
从第2行开始,接下来的m行表示每个社团的成员总人数和成员编号,每一行的第1个数字k表示该社团成员总人数,接下来的k个数字表示每一个成员的编号。例:
100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2
输出:被隔离学生总人数。例:
4
源代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define debug() puts("++++")
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a,b,sizeof(a))
#define sz size()
#define be begin()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
#define all 1,n,1
#define rep(i,n,x) for(int i=(x); i<(n); i++)
#define in freopen("in.in","r",stdin)
#define out freopen("out.out","w",stdout)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e18;
const int MAXN =  1e3 + 5;
const int maxm = 1e6 + 10;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int dx[] = {-1,1,0,0,1,1,-1,-1};
const int dy[] = {0,0,1,-1,1,-1,1,-1};
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/*
100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2

4
*/
int n,m;
int fa[maxm],a[maxm];
void init()
{
    for(int i=0;iint Find(int x)
{
    return fa[x]==x?fa[x]:Find(fa[x]);
}
void join(int x,int y)
{
    x=Find(x),y=Find(y);
    if(x!=y){
        fa[x]=y;
    }
}
int main()
{
    int x1,x2;
    cin>>n>>m;
    init();
    for(int i=0;iint k;
        cin>>k;
        cin>>x1;
        for(int j=1;jcin>>x2;
            join(x1,x2);
        }
    }
    int cnt=0;
    for(int i=0;iif(Find(i)==fa[0]){
            cnt++;
        }
    }
    cout<
  1. 编程实现Kruskal 算法,求图的最小生成树。
    输入:顶点编号及边权重。例:
    0 1 10
    0 2 15
    1 2 50
    输出:最小生成树。例:
    0 1 10
    0 2 15
    源代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define debug() puts("++++")
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a,b,sizeof(a))
#define sz size()
#define be begin()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
#define all 1,n,1
#define rep(i,n,x) for(int i=(x); i<(n); i++)
#define in freopen("in.in","r",stdin)
#define out freopen("out.out","w",stdout)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e18;
const int MAXN =  1e3 + 5;
const int maxm = 1e6 + 10;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int dx[] = {-1,1,0,0,1,1,-1,-1};
const int dy[] = {0,0,1,-1,1,-1,1,-1};
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int n,m;
int fa[maxm];
struct node
{
    int x,y,w;

}a[maxm],b[maxm];
bool cmp(node a, node b)
{
    return a.wint Find(int x)
{
    return fa[x]==x?x:fa[x]=Find(fa[x]);
}
void kurskal()
{
     for(int i=0;i<=n;i++)
        fa[i]=i;
    int cnt = 0, max = -1;
    for(int i=0; iint fx=Find(a[i].x);
        int fy=Find(a[i].y);
        if(fx!=fy){
            fa[fx]=fy;
            b[cnt].x=a[i].x;
            b[cnt].y=a[i].y;
            b[cnt++].w=a[i].w;
        }
    }
    for(int i=0;iprintf("%d %d %d\n",b[i].x,b[i].y,b[i].w);
    }
}
int main()
{
    cin>>n>>m;
    for(int i=0;icin>>a[i].x>>a[i].y>>a[i].w;
    }
    int cnt = 0;
    sort(a,a+m,cmp);
    kurskal();
}

你可能感兴趣的:(基础练习,ACM)