A.解不等式
题目描述
给定n个变量和m个不等式,每个不等式形如 x[i] - x[j] <= a[k] (0 <= i j < n 0 <= k < m, a[k]已知),求 x[n-1] - x[0] 的最大值。
输入
第一行 nm 表示的是n个变量和 m个不等式
接下来的 m行 会输入三个数abc 表示Xa-Xb<=c;
输出
输出一行结果 表示 Xn-1-X0的最大值。
样例输入
4 5
1 0 2
2 0 7
3 0 8
2 1 3
3 2 2
样例输出
7
AC code
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2500 + 5;
#define INF 0x3f3f3f3f
#define mem(a) memset(a,0,sizeof a)
int Map[maxn][maxn];
int dis[maxn],check[maxn];
int n,m,s,e,a,b,c;
int dijkstra(int n,int m,int s,int e){
mem(check);mem(dis);
for(int i=1;i<=n;i++){
dis[i]=Map[s][i];
}
check[s]=1,dis[s]=0;
int minx=0,pos;
for(int i=1;i<n;i++){
minx = INF;
for(int j=1;j<=n;j++){
if(!check[j] && minx > dis[j]){
minx = dis[j];
pos = j;
}
}
check[pos] = 1;
for(int j=1;j<=n;j++){
if(!check[j] && dis[j] > dis[pos] + Map[pos][j]){
dis[j] = dis[pos] + Map[pos][j];
}
}
}
return dis[e];
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
Map[i][j] = INF;
}
}
for(int i=1;i<=m;i++){
cin>>a>>b>>c;
//a++;b++;
a+=1;b+=1;
if(a==s&&b==e){
Map[a][b] = c;
}else if(Map[a][b]>c){
Map[a][b] = Map[b][a] = c;
}
}
cout<<dijkstra(n,m,1,n)<<endl;
return 0;
}
B.Jungle Roads
样例输入
9
A 2 B 12 I 25
B 3 C 10 H 40 I 8
C 2 D 18 G 55
D 1 E 44
E 2 F 60 G 38
F 0
G 1 H 35
H 1 I 35
3
A 2 B 10 C 40
B 1 C 20
0
样例输出
216
30
AC code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 50;
const int maxv=2500;
int per[maxn];
struct edge{
int u,v,w;
}e[maxv];
bool compare(edge a,edge b){
return a.w<b.w;
}
int find(int x){
if(per[x]==x)return x;
per[x]=find(per[x]);
return per[x];
}
int join(int x,int y){
int fx=find(x);
int fy=find(y);
if(fx!=fy){
per[fy]=fx;
return 1;
}
return 0;
}
int kruskal(int nn,int n){
int cont=0;
int ans=0;
for(int i=1;i<=nn;i++){
if(join(e[i].u,e[i].v)){
cont++;
ans+=e[i].w;
}
if(cont==n-1)break;
}
return ans;
}
int main()
{
int n;
while(scanf("%d",&n)&&n){
for(int i=0;i<maxn;i++){
per[i]=i;
}
char s[2];
int a;
int cnt=0;
for(int i=1;i<n;i++){
scanf("%s %d",s,&a);
for(int j=1;j<=a;j++){
int b;
scanf("%s %d",s,&b);
int uu=i;int vv=s[0]-'A'+1;
e[++cnt].u=uu;e[cnt].v=vv;
e[cnt].w=b;
e[++cnt].u=vv;e[cnt].v=uu;
e[cnt].w=b;
}
}
sort(e+1,e+1+cnt,compare);
int ans=kruskal(cnt,n);
printf("%d\n",ans);
}
}
C.传递闭包
题目描述
近日我们组织了一场奶牛的算法比赛,每头奶牛都有自己的代码风格,所以一个厉害的选手在自己的代码风格上就已经完全体现了出来,现在我们给你一些关系表示两头牛之间谁更强一点,根据这些关系我们要确定所有的牛当中那些牛的位次是确定的。并输出确定位次的奶牛数目。
输入
输入第一行两个数字nm分别表示 n 代表奶牛的数目,m代表的是关系的数目。
接下来的m行输入两个数字ab代表的是a比b要厉害所以他的排名也应该在b的前面。
输入范围 满足int数据类型
输出
输出一行代表可以确定位次的牛的数目。
样例输入
5 5
4 3
4 2
3 2
1 2
2 5
样例输出
2
AC code
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000 + 5;
int n,m,a,b;
int num[maxn][maxn];
void warshall(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(num[j][i]){
for(int k=1;k<=n;k++){
num[j][k]=num[j][k]|num[i][k];
}
}
}
}
}
int main(){
cin>>n>>m;
memset(num,0,sizeof num);
for(int i=1;i<=m;i++){
cin>>a>>b;
num[a][b]=1;
}
warshall();
/*for(int i = 1;i <= n;i++ ){
for(int j = 1;j <= n;j++){
cout<<num[i][j]<<" ";
}
cout<<endl;
}*/
int in[maxn],out[maxn];
memset(in,0,sizeof in);
memset(out,0,sizeof out);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(num[i][j]){
out[i]++;
in[j]++;
}
}
}
int ans = 0;
for(int i=1;i<=n;i++){
if(in[i]+out[i]==n-1)
ans++;
}
cout<<ans<<endl;
return 0;
}