河南多校大一训练赛 <思维--DP--背包--最短路--最大生成树>

每次比赛开始的状态都好差----开始的思路还不对--
无奈--被虐成皮了----


A - F是签到题
Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu

Description

Your karate club challenged another karate club in your town. Each club enters N players into the match, and each player plays one game against a player from the other team. Each game that is won is worth 2 points, and each game that is drawn is worth 1 point. Your goal is to score as many points as possible.

Your secret agents have determined the skill of every member of the opposing team, and of course you know the skill of every member of your own team. You can use this information to decide which opposing player will play against each of your players in order to maximize your score. Assume that the player with the higher skill in a game will always win, and if the players have the same skill then they will draw.

You will be given the skills of your players and of the opposing players, you have to find the maximum number of points that your team can score.

Input

Input starts with an integer T (≤ 70), denoting the number of test cases.

Each case starts with a line containing an integer N (1 ≤ N ≤ 50). The next line contains N space separated integers denoting the skills of the players of your team. The next line also contains N space separated integers denoting the skills of the players of the opposite team. Each of the skills lies in the range [1, 1000].

Output

For each case, print the case number and the maximum number of points your team can score.

Sample Input

4

2

4 7

6 2

2

6 2

4 7

3

5 10 1

5 10 1

4

10 7 1 4

15 3 8 7

Sample Output

Case 1: 4

Case 2: 2

Case 3: 4

Case 4: 5


开始以为和田忌赛马一样---
看着他们一个个A了---我却一个接一个的W--
想好最后A了---贡献7WA


代码:

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<algorithm>
using namespace std;
int wo[100],dui[100];
bool ww[100],dd[100];
int main()
{
	int t;scanf("%d",&t);
	for (int ca=1;ca<=t;ca++)
	{
		int n;scanf("%d",&n);
		for (int i=0;i<n;i++)
		scanf("%d",&wo[i]);
		for (int i=0;i<n;i++)
		scanf("%d",&dui[i]);
		sort(wo,wo+n);
		sort(dui,dui+n);
		int wk=0,wj=n-1,dj=n-1,dk=0,fen=0;
		
		memset(ww,true,sizeof(ww));
		memset(dd,true,sizeof(dd));
		//while (1)
        {
            bool fafe=false;
            for (int i=0;i<n;i++)
            {

                for (int jj=n-1;jj>=0;jj--)
                {
                    if (dd[jj]&&ww[i]==true&&wo[i]>dui[jj])
                    {
                        fen=fen+2;
                        dd[jj]=false;ww[i]=false;
                    }
                }
            }
            for (int i=0;i<n;i++)
            for (int j=dj;j>=dk;j--)
            {
                if (dd[j]&&ww[i]&&wo[i]==dui[j])
                {
                    fen=fen+1;
                    dd[j]=false;ww[i]=false;
                }
            }
        }
		printf("Case %d: %d\n",ca,fen);
	}
	return 0;
}



B - F是签到题
Time Limit:8000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

Nicholas Y. Alford was a cat lover. He had a garden in a village and kept many cats in his garden. The cats were so cute that people in the village also loved them.

One day, an evil witch visited the village. She envied the cats for being loved by everyone. She drove magical piles in his garden and enclosed the cats with magical fences running between the piles. She said “Your cats are shut away in the fences until they become ugly old cats.” like a curse and went away.

Nicholas tried to break the fences with a hummer, but the fences are impregnable against his effort. He went to a church and asked a priest help. The priest looked for how to destroy the magical fences in books and found they could be destroyed by holy water. The Required amount of the holy water to destroy a fence was proportional to the length of the fence. The holy water was, however, fairly expensive. So he decided to buy exactly the minimum amount of the holy water required to save all his cats. How much holy water would be required?

Input

The input has the following format:

N M
x
1 y1
.
.
.
xN yN
p1 q1
.
.
.
pM qM

The first line of the input contains two integers N (2 ≤ N ≤ 10000) and M (1 ≤ M). N indicates the number of magical piles and Mindicates the number of magical fences. The following N lines describe the coordinates of the piles. Each line contains two integers xiand yi (-10000 ≤ xiyi ≤ 10000). The following M lines describe the both ends of the fences. Each line contains two integers pj and qj (1 ≤pjqj ≤ N). It indicates a fence runs between the pj-th pile and the qj-th pile.

You can assume the following:

  • No Piles have the same coordinates.
  • A pile doesn’t lie on the middle of fence.
  • No Fences cross each other.
  • There is at least one cat in each enclosed area.
  • It is impossible to destroy a fence partially.
  • A unit of holy water is required to destroy a unit length of magical fence.

Output

Output a line containing the minimum amount of the holy water required to save all his cats. Your program may output an arbitrary number of digits after the decimal point. However, the absolute error should be 0.001 or less.

Sample Input 1

3 3
0 0
3 0
0 4
1 2
2 3
3 1

Output for the Sample Input 1

3.000

Sample Input 2

4 3
0 0
-100 0
100 0
0 100
1 2
1 3
1 4

Output for the Sample Input 2

0.000

Sample Input 3

6 7
2 0
6 0
8 2
6 3
0 5
1 7
1 2
2 3
3 4
4 1
5 1
5 4
5 6

Output for the Sample Input 3

7.236

Sample Input 4

6 6
0 0
0 1
1 0
30 0
0 40
30 40
1 2
2 3
3 1
4 5
5 6
6 4

Output for the Sample Input 4

31.000


-.-GG了--最大生成树都没有看出来---

题意:

一个人的猫被一个巫婆用魔法围起来了--

问最少需要破坏多长的距离使得没有猫被围---

即破坏边长小的边---尽量让长边留下---是不是有点最大生成树的感觉了---

先将所有的边加在一起--然后减去构成最大生成树的边即可--


代码:

#include<cstdio>
#include<cmath> 
#include<cstring>
#include<algorithm>
using namespace std;
double x[10200],y[10200];
double ju(int xx,int yy)
{return sqrt((x[xx]-x[yy])*(x[xx]-x[yy])+(y[xx]-y[yy])*(y[xx]-y[yy]));}
struct node{
	int a,b;
	double li;
}bian[1000000];
bool cmp(node xx,node yy)
{
	return xx.li>yy.li;
}
int fer[10200];
int find(int xx)
{
	if (xx==fer[xx]) return xx;
	return fer[xx]=find(fer[xx]); 
}
int main()
{
	int n,m;scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
	scanf("%lf%lf",&x[i],&y[i]);
	int a,b;double s=0,c;
	for (int i=0;i<m;i++)
	{
		scanf("%d%d",&a,&b);
		c=ju(a,b);
		s+=c;
		bian[i].a=a;bian[i].b=b;
		bian[i].li=c;
	}
	for (int i=1;i<=n;i++)
	fer[i]=i;
	sort(bian,bian+m,cmp);
	for (int i=0;i<m;i++)
	{
		a=find(bian[i].a);b=find(bian[i].b);
		if (a!=b)
		{
			s-=bian[i].li;
			fer[a]=b;
		}
	}
	printf("%.3lf\n",s);
	return 0;
}




C - F是签到题
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。 
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。 

Input

输入只包括一行5个整数x,y,m,n,L,其中x≠y < 2000000000,0 < m、n < 2000000000,0 < L < 2100000000。

Output

输出碰面所需要的跳跃次数,如果永远不可能碰面则输出一行"Impossible"

Sample Input

1 2 3 4 5

Sample Output

4



扩展欧几里得----还是晕晕的---


代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
LL GCD(LL xx,LL yy)
{
    if (yy==0)
        return xx;
    return GCD(yy,xx%yy);
}
LL egcd(LL a,LL b,LL &xx,LL &yy)
{
    if (b==0)
    {
        yy=0;xx=1;
        return a;
    }
    LL p=egcd(b,a%b,xx,yy);
    LL t=xx;xx=yy;yy=t-a/b*yy;
    return p;
}
int main()
{
    LL v,s,x,y,m,n,l;
    while (~scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l))
    {
        v=n-m;s=x-y;
        /*if (s<0)
        {
            s=l-s;
        }
        if (v<0)
        {
            v=-v;
            s=l-s;
        }*/
        LL gc=GCD(v,l);
        if (s%gc)
        {
            printf("Impossible\n");
            continue;
        }
        else
        {
            v/=gc;s/=gc;l/=gc;
             printf("%lld  %lld\n",v,s);
            LL xx,yy;
            egcd(v,l,xx,yy);
            xx=(s*xx-(LL)(s*xx/l)*l);//在s为负数时起作用---让xx变为正数--
            if (xx<0)
                xx+=l;
            printf("%lld\n",xx);
        }
    }
    return 0;
}



D - F是签到题
Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu

Description

If an integer is not divisible by 2 or 5, some multiple of that number in decimal notation is a sequence of only a digit. Now you are given the number and the only allowable digit, you should report the number of digits of such multiple.

For example you have to find a multiple of 3 which contains only 1's. Then the result is 3 because is 111 (3-digit) divisible by 3. Similarly if you are finding some multiple of 7 which contains only 3's then, the result is 6, because 333333 is divisible by 7.

Input

Input starts with an integer T (≤ 300), denoting the number of test cases.

Each case will contain two integers n (0 < n ≤ 106 and n will not be divisible by 2 or 5) and the allowable digit (1 ≤ digit ≤ 9).

Output

For each case, print the case number and the number of digits of such multiple. If several solutions are there; report the minimum one.

Sample Input

3

3 1

7 3

9901 1

Sample Output

Case 1: 3

Case 2: 6

Case 3: 12


----丫丫-------开始以为这样会超时不敢写----

此题已A成了线--我才敢这么暴力的写了一下---

是时候学一下计算时间复杂度了


代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int shu[1000000];
int main()
{
	int t;scanf("%d",&t);
	int n,k;
	
	for (int ca=1;ca<=t;ca++)
	{
		memset(shu,0,sizeof(shu));
		scanf("%d%d",&n,&k);
		int lp=k,yu;
		for (int i=1;;i++)
		{
			yu=lp%n;
			if (yu==0)
			{
				printf("Case %d: %d\n",ca,i);
				break;
			}
			if (shu[yu])
			{
				printf("Case %d: %d\n",ca,i-shu[yu]);
				break;
			}
			shu[yu]=i;
			lp=yu*10+k;
		}
	}
	return 0;
 } 



E - F是签到题
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

北大信息学院的同学小明毕业之后打算创业开餐馆.现在共有n 个地点可供选择。小明打算从中选择合适的位置开设一些餐馆。这 n 个地点排列在同一条直线上。我们用一个整数序列m1, m2, ... mn 来表示他们的相对位置。由于地段关系,开餐馆的利润会有所不同。我们用pi 表示在mi 处开餐馆的利润。为了避免自己的餐馆的内部竞争,餐馆之间的距离必须大于k。请你帮助小明选择一个总利润最大的方案。


Input

标准的输入包含若干组测试数据。输入第一行是整数T (1 <= T <= 1000) ,表明有T组测试数据。紧接着有T组连续的测试。每组测试数据有3行, 
第1行:地点总数 n (n < 100), 距离限制 k (k > 0 && k < 1000). 
第2行:n 个地点的位置m1 , m2, ... mn ( 1000000 > mi > 0 且为整数,升序排列) 
第3行:n 个地点的餐馆利润p1 , p2, ... pn ( 1000 > pi > 0 且为整数)

Output

对于每组测试数据可能的最大利润

Sample Input

23 111 2 1510 2 303 161 2 1510 2 30

Sample Output

4030


简单DP水过---

看题真不认真---最后才发现数据好小


代码:

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<algorithm>
using namespace std;
int di[120];
int p[120];
int qian[120];
int main()
{
	int t;scanf("%d",&t);
	while (t--)
	{
		int n,k;
		scanf("%d%d",&n,&k);
		int jian=0;
		for (int i=0;i<n;i++)
		{
			scanf("%d",&di[i]);
		//	jian+=k;
		//	di[i]-=jian;
		}
		for (int i=0;i<n;i++)
		scanf("%d",&p[i]);
		memset(qian,0,sizeof(qian));
		qian[0]=p[0];
		for (int i=1;i<n;i++)
		{
			int pp=0,ii=-1;
			for (int j=0;j<i;j++)
			{
				if (di[i]-di[j]>k&&qian[j]>pp)
				{
					pp=qian[j];
				}
			}
			qian[i]=pp+p[i];
		}
		int pp=0;
		for (int i=0;i<n;i++)
		{
			pp=max(qian[i],pp);
		}
		printf("%d\n",pp);
	}
	return 0;
}


F - 这个是签到题
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

来春卒業するAさんは,就職を機に引越しをすることにしました。就職する会社は,オフィスがい くつかの町にあって、日によって出勤するオフィスが違います。そこでAさんは,どこのオフィスに 行くにも時間の短い町に住もうと考えました。

そこであなたは、Aさんを助けるため、住むのに一番便利な町を探すことになりました。

町には0から始まる番号が振られており、町と町の間には道があります。それぞれの道に対して通 勤時間が決まっています。Aさんがある町に住んでいる場合に、自分の町のオフィスまでの通勤時間 は0とします。このときに全ての町までの通勤時間の総和を考えます。例えば,町と道の配置が上の 図のようになっていて、Aさんが町1に住んだ場合には、それぞれの町までの通勤時間は

   町0まで 80
   町1まで  0
   町2まで 20
   町3まで 70
   町4まで 90

となり、総和は260となります。

道の数と、全ての道の情報を入力とし、それぞれの町に住んだ場合の通勤時間の総和を計算し、そ れが最小となる町の番号と、そのときの通勤時間の総和を出力するプログラムを作成してください。 ただし、通勤時間の総和が最小となる町が複数ある場合は、一番小さい町の番号及びその時の通勤時 間の総和を出力してください。町の総数は10以下、道の総数は45以下とし、全ての道は双方向に移動 でき、通勤時間は方向によって変わらないものとします。また、どの町からでもその他全ての町への 経路があるものとします。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロひとつの行で示されま す。 各データセットは以下のとおりです。

 1行目  道の数n(整数)
 2行目  第1の道の情報 a1 b1 c1(それぞれ整数;半角空白区切り)
              各記号の意味は以下のとおりです。
              a1 b1:この道がつないでいる町の番号
              c1:a1、b1間の通勤時間
 3行目 第2の道の情報 a2 b2 c2
     :
 n+1行目 第nの道の情報 an bn cn

Output

入力データセット毎に通勤時間の総和が最小になる町の番号及びその時の通勤時間の総和を出力し ます。(半角空白区切り)

Sample Input

6     
0 1 80
1 2 20
0 2 60
2 3 50
3 4 60
1 4 90
2
0 1 1
1 2 1
0

Output for the Sample Input

2 240
1 2


-----最短路


代码:

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<algorithm>
using namespace std;
int lu[15][15],dis[15];
bool fafe[15],guo[15];int nn;
int disk(int xx)
{
//	printf("%d    66\n",xx);
	memset(guo,true,sizeof(guo));
	for (int i=0;i<=nn;i++)
	{
		dis[i]=lu[i][xx];
//		printf("%d   %d 8888\n",i,dis[i]);
	}
	
	guo[xx]=false;
	int pp=nn,lp=0;
	while (pp--)
	{
		int ii,mi=99999999;
		for (int i=0;i<=nn;i++)
		{
			if (guo[i]&&dis[i]<mi)
			{
				mi=dis[i];ii=i;
			}
		}
		lp+=mi;
		guo[ii]=false;
	//	printf("%d\n",ii);
		for (int i=0;i<=nn;i++)
		{
		//	printf("6666      %d   %d  %d\n",guo[i],dis[i],mi+lu[ii][i]);
			if (guo[i]&&dis[i]>mi+lu[ii][i])
			{
				dis[i]=mi+lu[ii][i];
		//		printf("kkkkkkkkkkkkk\n");
			}
		}
	}
	return lp;
}
int main()
{
	int n,a,b,c;
	while (scanf("%d",&n),n)
	{
		for (int i=0;i<15;i++)
		for (int j=0;j<15;j++)
		lu[i][j]=49999999;
		nn=0;
	//	printf("%d   wuyu\n",lu[0][0]);
		memset(fafe,false,sizeof(fafe));
		for (int i=0;i<n;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			lu[a][b]=lu[b][a]=min(lu[a][b],c);
			nn=max(nn,a);nn=max(nn,b);
		}
		
		int he[13],ans;
	//	printf("%d\n",nn);
		for (int i=0;i<=nn;i++)
		{
		//	printf("%d  %d   guo\n",i,nn);
			he[i]=disk(i);
		//	printf("jie    %d\n",he[i]);
		}
		
		int mi=0xffffff;
		for (int i=0;i<=nn;i++)
		{
			if (he[i]<mi)
			{
				mi=he[i];
				ans=i;
			}
		}
		printf("%d %d\n",ans,he[ans]);
	}
	return 0;
}


G - F是签到题
Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

Description

宇航员Bob有一天来到火星上,他有收集硬币的习惯。于是他将火星上所有面值的硬币都收集起来了,一共有n种,每种只有一个:面值分别为a1,a2… an。 Bob在机场看到了一个特别喜欢的礼物,想买来送给朋友Alice,这个礼物的价格是X元。Bob很想知道为了买这个礼物他的哪些硬币是必须被使用的,即Bob必须放弃收集好的哪些硬币种类。飞机场不提供找零,只接受恰好X元。

Input

第一行包含两个正整数n和x。(1 <= n <= 200, 1 <= x <= 10000) 
第二行从小到大为n个正整数a1, a2, a3 … an (1 <= ai <= x)

Output

第一行是一个整数,即有多少种硬币是必须被使用的。 
第二行是这些必须使用的硬币的面值(从小到大排列)。

Sample Input

5 18
1 2 3 5 10

Sample Output

2
5 10

Hint

输入数据将保证给定面值的硬币中至少有一种组合能恰好能够支付X元。 
如果不存在必须被使用的硬币,则第一行输出0,第二行输出空行。


背包:----先加入--后减去---


代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int ying[202],ans[202],kk;
int bao[10200],f[10200]; 
int main()
{
	int n,x,y;scanf("%d%d",&n,&x);
	for (int i=1;i<=n;i++)
	scanf("%d",&ying[i]);
	memset(bao,0,sizeof(bao));
	bao[0]=1;
	for (int i=1;i<=n;i++)
	for (int j=x;j>=ying[i];j--)
	bao[j]=bao[j]+bao[j-ying[i]];
	kk=0;
	for (int i=1;i<=n;i++)
	{
		memset(f,0,sizeof(f));
		for (int j=0;j<=x;j++)
		if (j>=ying[i])
		f[j]=bao[j]-f[j-ying[i]];
		else f[j]=bao[j];
		if (f[x]==0)
		ans[kk++]=ying[i];
	}
	printf("%d\n",kk);
	for (int i=0;i<kk-1;i++)
	printf("%d ",ans[i]);
	if (kk)
	printf("%d",ans[kk-1]);
	printf("\n");
	return 0;
} 



I - F是签到题
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M ≤ 100,000) unidirectional (one-way roads connects pairs of farms; road i requires Ti (1 ≤ Ti ≤ 100) units of time to traverse.

Each cow must walk to the party and, when the party is over, return to her farm. Each cow is lazy and thus picks an optimal route with the shortest time. A cow's return route might be different from her original route to the party since roads are one-way.

Of all the cows, what is the longest amount of time a cow must spend walking to the party and back?

Input

Line 1: Three space-separated integers, respectively:  NM, and  X 
Lines 2..  M+1: Line  i+1 describes road  i with three space-separated integers:  AiBi, and  Ti. The described road runs from farm  Ai to farm  Bi, requiring  Ti time units to traverse.

Output

Line 1: One integer: the maximum of time any one cow must walk.

Sample Input

4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3

Sample Output

10

Hint

Cow 4 proceeds directly to the party (3 units) and returns via farms 1 and 3 (7 units), for a total of 10 time units.



代码;

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<algorithm>
using namespace std;
int lu[1010][1010],qu[1010][1010],dis[1010],edis[1010];
bool guo[1010];
int nn;
int disk(int xx)
{
	memset(guo,true,sizeof(guo));
	for (int i=1;i<=nn;i++)
	{
		dis[i]=lu[xx][i];
	}
	guo[xx]=false;
	int pp=nn-1,lp=0;
	while (pp--)
	{
		int ii,mi=99999999;
		for (int i=1;i<=nn;i++)
		{
			if (guo[i]&&dis[i]<mi)
			{
				mi=dis[i];ii=i;
			}
		}
		lp=mi;
		guo[ii]=false;
		for (int i=1;i<=nn;i++)
		{
			if (guo[i]&&dis[i]>mi+lu[ii][i])
			{
				dis[i]=mi+lu[ii][i];
			}
		}
	}
}
int di(int xx)
{
	memset(guo,true,sizeof(guo));
	for (int i=1;i<=nn;i++)
	{
		edis[i]=qu[xx][i];
	}
	guo[xx]=false;
	int pp=nn-1,lp=0;
	while (pp--)
	{
		int ii,mi=99999999;
		for (int i=1;i<=nn;i++)
		{
			if (guo[i]&&edis[i]<mi)
			{
				mi=edis[i];ii=i;
			}
		}
		lp=mi;
		guo[ii]=false;
		for (int i=1;i<=nn;i++)
		{
			if (guo[i]&&edis[i]>mi+qu[ii][i])
			{
				edis[i]=mi+qu[ii][i];
			}
		}
	}
	return lp;
}
int main()
{
	int n,a,b,c,m,x;
//	while (scanf("%d%d%d",&n,&m,&x))
scanf("%d%d%d",&n,&m,&x);
	{
		for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
		{
			lu[i][j]=49999999;
			qu[i][j]=49999999;
		}
		for (int i=0;i<m;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			lu[a][b]=min(lu[a][b],c);
			qu[b][a]=min(qu[b][a],c);
		}
		int ans;
		nn=n;
		disk(x);
		di(x);
		int mi=0;
		for (int i=1;i<=n;i++)
		{
			if (i!=x&&dis[i]+edis[i]>mi)
			mi=dis[i]+edis[i];
		}
		printf("%d\n",mi);
	}
	return 0;
}


单向路一区一回---

可反向记录路线---然后每个点去集合时从集合处通过反向路线计算路程


J - F是签到题
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

Bessie has been hired to build a cheap internet network among Farmer John's N (2 <= N <= 1,000) barns that are conveniently numbered 1..N. FJ has already done some surveying, and found M (1 <= M <= 20,000) possible connection routes between pairs of barns. Each possible connection route has an associated cost C (1 <= C <= 100,000). Farmer John wants to spend the least amount on connecting the network; he doesn't even want to pay Bessie. 

Realizing Farmer John will not pay her, Bessie decides to do the worst job possible. She must decide on a set of connections to install so that (i) the total cost of these connections is as large as possible, (ii) all the barns are connected together (so that it is possible to reach any barn from any other barn via a path of installed connections), and (iii) so that there are no cycles among the connections (which Farmer John would easily be able to detect). Conditions (ii) and (iii) ensure that the final set of connections will look like a "tree".

Input

* Line 1: Two space-separated integers: N and M 

* Lines 2..M+1: Each line contains three space-separated integers A, B, and C that describe a connection route between barns A and B of cost C.

Output

* Line 1: A single integer, containing the price of the most expensive tree connecting all the barns. If it is not possible to connect all the barns, output -1.

Sample Input

5 8
1 2 3
1 3 7
2 3 10
2 4 4
2 5 8
3 4 6
3 5 2
4 5 17

Sample Output

42

Hint

OUTPUT DETAILS: 

The most expensive tree has cost 17 + 8 + 10 + 7 = 42. It uses the following connections: 4 to 5, 2 to 5, 2 to 3, and 1 to 3.


最大生成树水过


代码:

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m;
struct node{
	int a,b,c;
}lu[20200];
int fer[1020];
bool cmp(node xx,node yy)
{
	return xx.c>yy.c;
}
int find(int xx)
{
	if (xx==fer[xx])
	return xx;
	return fer[xx]=find(fer[xx]);
}
int main()
{
//	int t;scanf("%d",&t);
//	for (int ca=1;ca<=t;ca++)
	while (~scanf("%d%d",&n,&m))
	{
		
		int aa,bb,cc;
		for (int i=0;i<m;i++)
		{
			scanf("%d%d%d",&lu[i].a,&lu[i].b,&lu[i].c);
		}
		sort(lu,lu+m,cmp);
		for (int i=0;i<=n;i++)
		fer[i]=i;
		int s=0,pp=0;
		for (int i=0;i<m;i++)
		{
			aa=lu[i].a;bb=lu[i].b;cc=lu[i].c;
			if (find(aa)!=find(bb))
			{
				s+=cc;
				pp++;
				fer[find(aa)]=find(bb);
			}
		}
		if (pp==n-1)
		printf("%d\n",s);
		else
		printf("-1\n");
	}
	return 0;
}






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值