A. 修路 2014新生暑假个人排位赛06
题目描述
小弱的学校很喜欢修路,现在给你一张他学校的地图,地图上有n个点和m条双向边,每条边代表一条路,这条路有可能是畅通,也有可能正在修路。大家都知道修路使得交通很不方便。所有小弱很想学校快快的把路修好,使得他能够很轻松的到达主楼915去刷题。但考虑到学校的施工能力有限,小弱想让你帮他算出学校需要集中力量马上修好的最少路数,使得他能够从学校任意点出发,在不经过正在施工的路下到达主楼(编号为1)。
输入格式
有多组数据。
每组数据以n( 1<=n<=10000), m(1<=m<=200000)开头。接下来一行有m行数。每行有三个数,对应于u, v, s,分别为这条路的两端点(编号从1到n)和路况,s = 0代表畅通, s = 1 代表正在修路。输入保证图是连通图。
输出格式
对每组数据输出对应的最少路数。
输入样例
3 2
1 2 0
1 3 1
3 2
1 2 0
1 3 0
3 2
1 2 1
1 3 1
输出样例
1
0
2
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int father[10010],rank[10010],vis[10010];
int find(int x){
if(x==father[x])return x;
else return father[x]=find(father[x]);
}
void unite(int x,int y){
x=find(x);
y=find(y);
father[x]=y;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)){
for(int i=0;i<=n;i++)
father[i]=i;
for(int i=0;i<m;i++){
int u,v,s;
scanf("%d%d%d",&u,&v,&s);
if(s==0) unite(u,v);
}
int ans=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
vis[find(i)]=1;
for(int i=1;i<=n;i++)
if(vis[i])
ans++;
printf("%d\n",ans-1);
}
return 0;
}
445. 高兴
题目描述
小弱有n个玩具,现在小弱想把他们排列成一行,把玩具j放在玩具i的右边相邻的位置上,他将得到一个高兴值Hij.
输入格式
输入有多组数据。
每组数据以一个整数n(n <= 18)开头。
接下来n行, 每行n个整数。 第i行第j列Hij( Hij的绝对值 <= 10000)代表把玩具j放在玩具i的右边相邻的位置时高兴值。输入保证Hii = 0,最左边只考虑与右边相邻的玩具,最右边只考虑与左边相邻的玩具。
输出格式
对于每组数据输出最大高兴值。
输入样例
2
0 1
2 0
3
0 -1 7
3 0 3
3 3 0
输出样例
2
10
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define INF 200000
using namespace std;
int n;
int d[19][19];
int dp[1<<19][19];
int vis[1<<19][19];
int rec(int S,int v){
if(vis[S][v]==1)
return dp[S][v];
if(S==(1<<n)-1)
return dp[S][v]=0;
int res=-INF;
for(int u=0;u<n;u++)
if(!(S>>u&1))
res=max(res,rec(S|1<<u,u)+d[v][u]);
vis[S][v]=1;
return dp[S][v]=res;
}
int main()
{
while(~scanf("%d",&n)){
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&d[i][j]);
int ans=-INF;
for(int i=0;i<n;i++)
ans=max(ans,rec(1<<i,i));
printf("%d\n",ans);
}
return 0;
}
问了zsp,借鉴了她的代码,旅行商问题,晓得了。
449. 排序
题目描述
给你n个数,请你将他们从小到大输出出来。
输入格式
多组数据。
输入第一行为n,接下来一行给出n个数,每个数在0到10000。
输入文件大小为8.2MB。
输出格式
输出一行,排序之后的n个数。
输入样例
3
4 2 1
输出样例
1 2 4
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
int a[10001];
int vis[10001];
int main()
{
int n;
while(~scanf("%d",&n)){
memset(vis,0,sizeof(vis));
if(n<2000){
int num=0;
for(int i=0;i<n;i++){
int x;
scanf("%d",&x);
if(vis[x]==0) a[num++]=x;
vis[x]++;
}
sort(a,a+num);
for(int i=0;i<num;i++)
while(vis[a[i]]!=0){
vis[a[i]]--;
printf("%d ",a[i]);
}
printf("\n");
}
else {
int MAX=-1,MIN=10001;
for(int i=0;i<n;i++){
int x;
scanf("%d",&x);
a[x]++;
if(x>MAX) MAX=x;
if(x<MIN) MIN=x;
}
for(int i=MIN;i<=MAX;i++)
while(a[i]!=0){
a[i]--;
printf("%d ",i);
}
printf("\n");
}
}
return 0;
}
444. 爱好和平
题目描述
在星际时代,每个帝国都靠着贸易路线连接着各个联盟星球,这些贸易路线都是双向可达的。一个帝国的综合实力由他贸易连接着的联盟星球数决定。
学姐作为Mays帝国的领袖,长期与Luke帝国保持着敌对关系,爱好和平的学姐希望结束长达几个世纪的战争,于是找实验室定做了一颗代号小苹果的炸弹,可以定点摧毁一颗星球,这颗星球被毁后,与它相连的全部贸易就都被切断了,这样Luke帝国可能就被切断为一个小联盟,他们就再也不会对学姐的地位构成威胁啦~
经过调查,Luke帝国为了节约经费,他的联盟星之间都有且仅有一条直接或间接的贸易通路。
现在给出Luke帝国的贸易线路,学姐想知道摧毁哪一颗行星可以使得分裂后的若干Luke联盟威胁最大的分部最小。
输入格式
输入有多组数据,组数不大于10组。每一组开头一行为n,m,表示Luke帝国的联盟星球数量,和贸易关系数,接下来m行,每行两个整数u,v,表示星球u,v之间存在直接的贸易路线,1<=u,v<=n,1<=n,m<=100000
输出格式
输出一个数表示推荐学姐摧毁的星球,如果有多解,输出编号最小的一个。
输入样例
5 4
1 2
1 3
1 4
4 5
输出样例
1
/*
USER_ID: test#wlwlxgg
PROBLEM: 444
SUBMISSION_TIME: 2014-07-27 23:50:17
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define INF 100010
using namespace std;
struct {int to,next;}e[200010];
int head[100010],cnt;
int n,m;
int dp[100010],num[100010];
void add(int u,int v){
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
cnt++;
}
void init(){
for(int i=0;i<=n;i++){
head[i]=0;
dp[i]=0;
num[i]=0;
}
cnt=1;
}
int dfs(int u,int fa){
num[u]=1;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa)continue;
else num[u]+=dfs(v,u);
}
dp[u]=n-num[u];
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa)continue;
else dp[u]=max(num[v],dp[u]);
}
return num[u];
}
int main()
{
while(~scanf("%d%d",&n,&m)){
init();
for(int i=0;i<m;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs(1,0);
int ans=INF;
for(int i=1;i<=n;i++)
ans=min(ans,dp[i]);
for(int i=1;i<=n;i++)
if(ans==dp[i])
{printf("%d\n",i);break;}
}
return 0;
}