您的位置:首页 > 其它

SHU_OJ 1929:Yaoge的英语成绩题解

2015-07-25 18:08 337 查看
Description

Yaoge和小伙伴们终于拿到了英语测试的成绩,大家开始讨论起各自的成绩,然而Yaoge身边都是智(yan)商(zhi)报表的同学们,他们不喜欢报出自己的成绩,只会说“我至少有XX分”,“我比XX至少高XX分”。

作为Yaoge的朋友,你想知道他的成绩,于是你整理出了这两类信息:

1. A的成绩至少是X分。(ScoreA >= X)

2. A至少比B高X分。(ScoreA - ScoreB >= X)

利用这些信息,请求出Yaoge的英语成绩至少为多少分。

*注意每一位同学的分数都必须是非负整数。



Input



第一行是一个整数T,表示数组组数(T<=20)。

每一组数据第一行有三个整数N、P、Q,表示总人数为N,其中一直的第一类信息有P条,第二类信息有Q条。

(1 <= N <= 100, 0 <= P <= N, 0 <= Q <= 1000)

之后先有P行,每行有两个整数A、X,表示A的成绩至少为X分。

接着有Q行,每行有三个整数A、B、X,表示A至少比B高X分。

(1 <= A, B <=N, 1 <= X <= 1000)

*A、B表示同学的编号,其中1号表示Yaoge。

Output



对于每一组数据,输出一行整数,表示Yaoge的成绩的最小可能值。

Sample Input

2

1 0 0

3 1 2

2 570

3 2 30

1 3 112



Sample Output

0

712



HINT

update: 注意可能有重边!



Source

Curs0r

这道题对于初学竞赛的人来说还是要费一番脑筋的。我也是花了将近两个小时才把这道题搞定(我也是菜鸟)。大部分要说的内容标注在注释上,代码如下:

#include <iostream> 
#include <sstream> 
#include <ios> 
#include <iomanip> 
#include <functional> 
#include <algorithm> 
#include <vector> 
#include <string> 
#include <list> 
#include <queue> 
#include <deque> 
#include <stack> 
#include <set> 
#include <map> 
#include <cstdio> 
#include <cstdlib> 
#include <cmath> 
#include <cstring> 
#include <climits> 
#include <cctype> 
#define INF 0x3f3f3f3f 
#define MP(X,Y) make_pair(X,Y) 
#define PB(X) push_back(X) 
#define REP(X,N) for(int X=0;X<N;X++) 
#define REP2(X,L,R) for(int X=L;X<=R;X++) 
#define DEP(X,R,L) for(int X=R;X>=L;X--) 
#define CLR(A,X) memset(A,X,sizeof(A)) 
#define IT iterator 
#define M_PI 3.14159265358979323846 
#define _ ios_base::sync_with_stdio(0);cin.tie(0); 
#define X first 
#define Y second 
#define MAX_V 10101 
#define maxn 10 
#define lowbit(X) (X & (-X)) 
#include<ctime> 
using namespace std; 
typedef long long ll; 
typedef pair<int,int>PII; 
typedef pair<PII,int>PPI; 
  
/************************************************
********************头文件**********************
************************************************/  
int G[101][101]; //G[i][j]表示i比j最少高G[i][j]
int T[101]; //T[i]表示i最少的分数
int P[101]; //过度T[]
int main() 
{ 
    int t; 
    cin>>t; 
    while(t--) 
    { 
        int n,p,q; 
        cin>>n>>p>>q; 
        memset(G,0,sizeof(G)); ///
        memset(T,0,sizeof(T)); /////初始化
        memset(P,0,sizeof(P)); ///
          
        int a,b,x; 
        REP(i,p) 
        { 
            cin>>a>>x; 
            a--; 				//编号从0开始
            T[a] = x; 			//记录分数
        } 
        REP(i,q) 
        { 
            cin>>a>>b>>x; 
            a--;b--; 
            if(x>G[a][b]) //因为标明可能有多组数据就必然有多组数据
            G[a][b] = x; //始终保持取到较大的差值
        } 
        REP(i,min(n,q)) //取n,q中的小值就可以完成全部更新
        { 
            REP(j,n) 
            REP(k,n) //循环遍历每个条件
            { 
                int g; 
                g = G[j][k]; //g >0 题中已注明
                if(g != 0&&T[j]-T[k]<g) //将需要更新分数的进行记录,如果直接更新会出错
                { 
                    //cout<<j<<" "<<k<<" "<<T[j];  
                    if(P[j]<T[k]+g)P[j] = T[k] + g; 
                    //cout<<" "<<P[j]<<endl; 
                } 
                  
            } 
            REP(i,n) //将记录的分数更新
                { 
                    if(P[i] != 0) 
                        T[i] = P[i]; 
                      
                } 
            //cout<<endl;  
        } 
        cout<<T[0]<<endl; //输出第一个的分数
    } 
    return 0; 
}


这道题目不算很难用这种方法时间复杂度能够满足要求。也可以用pair把几个条件编号,每次只需遍历q次就可以更新一遍数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: