HDU_3468_Treasure Hunting([二分图匹配 / 最大流] + 最短路)

本文介绍了一款寻宝游戏的问题背景及解决方案。玩家需按指定顺序到达多个集合点,并尽可能多地收集途中的宝藏。文章详细解析了使用广度优先搜索预处理最短路径,构建二分图模型并通过最大匹配或最大流算法来确定可获取的最大宝藏数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Treasure Hunting

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 1605    Accepted Submission(s): 421



Problem Description
Do you like treasure hunting? Today, with one of his friend, iSea is on a venture trip again. As most movie said, they find so many gold hiding in their trip.
Now iSea’s clever friend has already got the map of the place they are going to hunt, simplify the map, there are three ground types:

● '.' means blank ground, they can get through it
● '#' means block, they can’t get through it
● '*' means gold hiding under ground, also they can just get through it (but you won’t, right?)

What makes iSea very delighted is the friend with him is extraordinary justice, he would not take away things which doesn’t belong to him, so all the treasure belong to iSea oneself!
But his friend has a request, he will set up a number of rally points on the map, namely 'A', 'B' ... 'Z', 'a', 'b' ... 'z' (in that order, but may be less than 52), they start in 'A', each time friend reaches to the next rally point in the shortest way, they have to meet here (i.e. iSea reaches there earlier than or same as his friend), then start together, but you can choose different paths. Initially, iSea’s speed is the same with his friend, but to grab treasures, he save one time unit among each part of road, he use the only one unit to get a treasure, after being picked, the treasure’s point change into blank ground.
Under the premise of his friend’s rule, how much treasure iSea can get at most?

 

Input
There are several test cases in the input.

Each test case begin with two integers R, C (2 ≤ R, C ≤ 100), indicating the row number and the column number.
Then R strings follow, each string has C characters (must be ‘A’ – ‘Z’ or ‘a’ – ‘z’ or ‘.’ or ‘#’ or ‘*’), indicating the type in the coordinate.

The input terminates by end of file marker.
 

Output
For each test case, output one integer, indicating maximum gold number iSea can get, if they can’t meet at one or more rally points, just output -1.

 

Sample Input
  
2 4 A.B. ***C 2 4 A#B. ***C
 

Sample Output
  
1 2
 

题意:在地图上从A -> B -> C …… -> Z -> a -> b …… -> z 这样走,每次走的都是最短路(可能多条路径),地图上有一些金子,如果在某一条最短路上存在金子,那么只取一个金子。问最多能取多少金子。

分析:先bfs预处理出每个点(A.B.C……)到其他点的最短路径,然后对于每个金子,判断其是否在某条最短路径上,假设gold1在(A -> B)的最短路径上,那么A连向gold1,依次类推,就建立了二分图模型了,然后求二分图最大匹配即可。若用网络流,那么所有的边容量设为1;加入超级源点s,连向所有的点(A.B.C……),容量为1;加入超级汇点t,所有的金子连向t,容量为1。然后跑一遍最大流。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3468

代码清单:

二分图匹配

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<cctype>
#include<string>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

#define end() return 0

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;

const int maxN = 100 + 5;
const int maxn = 10000 + 5;
const int maxv = 100000 + 5;
const int INF = 0x7f7f7f7f;

struct Node{
    int x,y;
    Node(){}
    Node(int _x,int _y):x(_x),y(_y){}
}rally[60];

int C,R;
char str[maxN][maxN];
int dist[60][10005];
int gold[10005],go;
bool vis[maxN][maxN];
int ra,tail;
vector<int>graph[60];
int match[maxn];
bool vist[maxn];

void init(){
    ra=-1; go=0;
    memset(dist,INF,sizeof(dist));
    memset(match,-1,sizeof(match));
    for(int i=0;i<60;i++) graph[i].clear();
}

int get_rally(char s){
    if(s>='A'&&s<='Z') return s-'A'+1;
    if(s>='a'&&s<='z') return s-'a'+27;
    return 0;
}

void input(){
    for(int i=0;i<C;i++){
        scanf("%s",str[i]);
        for(int j=0;j<R;j++){
            if(str[i][j]=='*') gold[go++]=i*R+j;
            else{
                int idx=get_rally(str[i][j]);
                if(idx){ rally[idx]=Node(i,j); ra=max(ra,idx);}
            }
        }
    }
}

int X[]={0,-1,0,1};
int Y[]={-1,0,1,0};

void bfs(int idx,Node s){
    memset(vis,false,sizeof(vis));
    queue<Node>q;
    while(!q.empty()) q.pop();
    q.push(s);
    vis[s.x][s.y]=true;
    dist[idx][s.x*R+s.y]=0;
    while(!q.empty()){
        Node p=q.front();q.pop();
        for(int i=0;i<4;i++){
            int xx=p.x+X[i];
            int yy=p.y+Y[i];
            if(xx>=0&&xx<C&&yy>=0&&yy<R&&!vis[xx][yy]&&str[xx][yy]!='#'){
                vis[xx][yy]=true;
                q.push(Node(xx,yy));
                dist[idx][xx*R+yy]=dist[idx][p.x*R+p.y]+1;
            }
        }
    }

}

void createGraph(){
    for(int i=1;i<ra;i++){
        int idx=rally[i+1].x*R+rally[i+1].y;
        for(int j=0;j<go;j++){
            if(dist[i][gold[j]]+dist[i+1][gold[j]]==dist[i][idx])
                graph[i].push_back(ra+j+1);
        }
    }
}

bool dfs(int u){
    for(int i=0;i<graph[u].size();i++){
        int v=graph[u][i];
        if(!vist[v]){
            vist[v]=true;
            if(match[v]==-1 || dfs(match[v])){
                match[v]=u;
                return true;
            }
        }
    }return false;
}

void solve(){
    for(int i=1;i<=ra;i++){
        bfs(i,rally[i]);
    }
    if(ra==1) {
        printf("-1\n");
        return ;
    }
    for(int i=1;i<ra;i++){
        int idx=rally[i+1].x*R+rally[i+1].y;
        if(dist[i][idx]==INF){
            printf("-1\n");
            return ;
        }
    }
    createGraph();
    int ans=0;
    for(int i=1;i<ra;i++){
        memset(vist,false,sizeof(vist));
        if(dfs(i)) ans++;
    }
    printf("%d\n",ans);
}

int main(){
    while(scanf("%d%d",&C,&R)!=EOF){
        init();
        input();
        solve();
    }end();
}

最大流dinic

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<cctype>
#include<string>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

#define end() return 0

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;

const int maxN = 100 + 5;
const int maxn = 10000 + 5;
const int maxv = 100000 + 5;
const int INF = 0x7f7f7f7f;

struct Edge{
    int from,to,cap,flow;
    Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};

struct dinic{
    int n,m,s,t; //结点数,边数(包括反向弧),源点,汇点
    vector<Edge>edge;//边表。edge[e]和edge[e^1]互为反向弧
    vector<int>G[maxn];//邻接表。G[i][j]表示结点i的第j条边在e数组的序号
    bool vis[maxn]; //bfs用
    int d[maxn]; //从起点到i的距离
    int cur[maxn]; //当前弧下标

    void init(int n,int s,int t){
        this -> n = n;
        this -> s = s;
        this -> t = t;
        for(int i=0;i<=n;i++) G[i].clear();
        edge.clear();
    }

    void addEdge(int from,int to,int cap){
        edge.push_back(Edge(from,to,cap,0));
        edge.push_back(Edge(to,from,0,0));
        m=edge.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }

    bool bfs(){
        memset(vis,false,sizeof(vis));
        queue<int>q;
        q.push(s);
        d[s]=0;
        vis[s]=true;
        while(!q.empty()){
            int x=q.front();q.pop();
            for(int i=0;i<G[x].size();i++){
                Edge& e=edge[G[x][i]];
                if(!vis[e.to]&&e.cap>e.flow){ //只考虑残量网络中的弧
                    vis[e.to]=true;
                    d[e.to]=d[x]+1;
                    q.push(e.to);
                }
            }
        }
        return vis[t];
    }

    int dfs(int x,int a){
        if(x==t||a==0) return a;
        int flow=0,f;
        for(int& i=cur[x];i<G[x].size();i++){ // & -> 从上次考虑的弧
            Edge& e=edge[G[x][i]];
            if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
                e.flow+=f;
                edge[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0) break;
            }
        }
        return flow;
    }

    int maxflow(){
        int flow=0;
        while(bfs()){
            memset(cur,0,sizeof(cur));
            flow+=dfs(s,INF);
        }
        return flow;
    }
};

struct Node{
    int x,y;
    Node(){}
    Node(int _x,int _y):x(_x),y(_y){}
}rally[60];

int C,R;
char str[maxN][maxN];
int dist[60][10005];
int gold[10005],go;
bool vis[maxN][maxN];
int ra,tail;
dinic dc;

void init(){
    ra=-1; go=0;
    memset(dist,INF,sizeof(dist));
}

int get_rally(char s){
    if(s>='A'&&s<='Z') return s-'A'+1;
    if(s>='a'&&s<='z') return s-'a'+27;
    return 0;
}

void input(){
    for(int i=0;i<C;i++){
        scanf("%s",str[i]);
        for(int j=0;j<R;j++){
            if(str[i][j]=='*') gold[go++]=i*R+j;
            else{
                int idx=get_rally(str[i][j]);
                if(idx){ rally[idx]=Node(i,j); ra=max(ra,idx);}
            }
        }
    }
}

int X[]={0,-1,0,1};
int Y[]={-1,0,1,0};

void bfs(int idx,Node s){
    memset(vis,false,sizeof(vis));
    queue<Node>q;
    while(!q.empty()) q.pop();
    q.push(s);
    vis[s.x][s.y]=true;
    dist[idx][s.x*R+s.y]=0;
    while(!q.empty()){
        Node p=q.front();q.pop();
        for(int i=0;i<4;i++){
            int xx=p.x+X[i];
            int yy=p.y+Y[i];
            if(xx>=0&&xx<C&&yy>=0&&yy<R&&!vis[xx][yy]&&str[xx][yy]!='#'){
                vis[xx][yy]=true;
                q.push(Node(xx,yy));
                dist[idx][xx*R+yy]=dist[idx][p.x*R+p.y]+1;
            }
        }
    }

}

void createGraph(){
    tail=ra+go+1;
    dc.init(tail+1,0,tail);
    for(int i=1;i<ra;i++){
        dc.addEdge(0,i,1);
        int idx=rally[i+1].x*R+rally[i+1].y;
        for(int j=0;j<go;j++){
            if(dist[i][gold[j]]+dist[i+1][gold[j]]==dist[i][idx])
                dc.addEdge(i,ra+j+1,1);
        }
    }
    for(int j=0;j<go;j++){
        dc.addEdge(j+ra+1,tail,1);
    }
}

void solve(){
    for(int i=1;i<=ra;i++){
        bfs(i,rally[i]);
    }
    if(ra==1) {
        printf("-1\n");
        return ;
    }
    for(int i=1;i<ra;i++){
        int idx=rally[i+1].x*R+rally[i+1].y;
        if(dist[i][idx]==INF){
            printf("-1\n");
            return ;
        }
    }
    createGraph();
    printf("%d\n",dc.maxflow());
}

int main(){
    while(scanf("%d%d",&C,&R)!=EOF){
        init();
        input();
        solve();
    }end();
}


<think>我们正在解决一个关于Hi3861开发板在OpenHarmony环境中编译MQTT相关示例时出现的文件路径错误问题。用户提到了几个关键路径:hi3861_hdu_iot_application,paho_mqtt,MQTTPacket,MQTTClient-C,ohos。我们需要根据引用内容来定位问题。根据引用[3],我们得知在Hi3861的示例程序中,有一个features列表,其中包含MQTT相关的示例(如"26_paho.mqtt.embedded-c:app")。用户可能是在编译这个示例时遇到了文件路径错误。常见问题(引用[1])包括:1.Sources源文件路径不正确2.Include_dirs头文件路径不正确3.JSON语法错误(如缺少逗号)4.注释处理不当因此,我们需要检查与MQTT示例相关的BUILD.gn文件,确保源文件和头文件路径正确,并且没有语法错误。步骤:1.确认MQTT库是否已经正确放置在vendor目录下。通常,第三方库(如paho.mqtt.embedded-c)应该放在vendor的某个子目录中。2.检查示例程序的BUILD.gn文件(如demo/BUILD.gn)中是否正确定义了源文件和头文件路径。3.检查依赖的库(如MQTTPacket、MQTTClient-C)是否在项目中存在,并且路径正确。具体到用户的问题,错误可能是由于在编译26号示例时,系统找不到paho.mqtt.embedded-c库的相关文件。我们需要查看该示例的构建脚本。根据引用[3]中的示例,我们注意到在demo/BUILD.gn中,每个feature对应一个示例程序。因此,26号示例对应的构建目标在features中为"26_paho.mqtt.embedded-c:app"。这个目标应该对应一个名为app.gn的文件,位于26_paho.mqtt.embedded-c目录下。我们需要检查这个app.gn文件中的路径设置。假设项目结构如下:```vendor└──hihope└──hispark_pegasus└──demo├──26_paho.mqtt.embedded-c│├──app.gn│└──...(源文件)└──BUILD.gn```在app.gn中,应该定义了源文件路径和头文件路径。例如:```python#示例app.gn内容import("//build/lite/config/component/lite_component.gni")executable("app"){output_name="app"sources=["paho_mqtt_demo.c",#其他源文件]include_dirs=["//vendor/hihope/hispark_pegasus/demo/26_paho.mqtt.embedded-c",#MQTT库的头文件路径"//vendor/paho.mqtt.embedded-c/MQTTPacket/src","//vendor/paho.mqtt.embedded-c/MQTTClient-C/src",]deps=["//vendor/paho.mqtt.embedded-c:MQTTPacket","//vendor/paho.mqtt.embedded-c:MQTTClient-C",]cflags=["-Wno-unused-variable"]}```同时,在vendor/paho.mqtt.embedded-c目录下,应该有两个库的构建目标(BUILD.gn文件),例如:```python#vendor/paho.mqtt.embedded-c/BUILD.gnstatic_library("MQTTPacket"){sources=["MQTTPacket/src/MQTTConnectClient.c","MQTTPacket/src/MQTTConnectServer.c",...#其他源文件]include_dirs=["MQTTPacket/src"]}static_library("MQTTClient-C"){sources=["MQTTClient-C/src/MQTTClient.c"]include_dirs=["MQTTPacket/src",#依赖MQTTPacket的头文件"MQTTClient-C/src"]deps=[":MQTTPacket"]}```解决方案:1.确认paho.mqtt.embedded-c库已经正确下载并放置在vendor目录下(可能是vendor/paho.mqtt.embedded-c)。2.检查26_paho.mqtt.embedded-c示例的app.gn文件中的include_dirs和deps是否指向正确的路径。3.检查paho.mqtt.embedded-c库的BUILD.gn文件是否存在,且语法正确(如逗号、括号等)。如果用户遇到找不到文件的问题,可能是路径大小写不一致,或者路径层级不对。需要确保在app.gn中引用的路径与实际目录结构一致。另外,根据引用[1],还要检查JSON配置(如果有)和注释符号的使用。如果用户是在修改后的代码中出现问题,请确保在BUILD.gn中取消注释了MQTT示例(即去掉26号前面的#号)。如果问题仍然存在,可以尝试以下步骤:-检查整个项目的目录结构,确保MQTT库的源文件和头文件在正确的位置。-查看编译错误信息,确定是哪个文件找不到,然后根据错误信息调整路径。注意:在OpenHarmony的构建系统中,路径通常从根目录开始(//表示根目录),因此要确保路径从根目录开始正确。例如,如果paho.mqtt.embedded-c库放在vendor目录下,则路径应为:`"//vendor/paho.mqtt.embedded-c/MQTTPacket/src"`。如果用户将库放在其他地方,则需要相应调整路径。后,如果用户使用的不是hihope的示例,而是自己的项目,那么需要在自己的BUILD.gn中正确配置这些路径。希望这些步骤能帮助用户解决问题。</think>针对Hi3861开发板在编译MQTT相关库时出现的文件路径错误问题,结合引用内容和OpenHarmony开发经验,解决方案如下: ### 问题分析 根据引用[3],MQTT示例(`26_paho.mqtt.embedded-c:app`)在`BUILD.gn`中属于可选编译项。路径错误通常由以下原因导致: 1. **头文件/源文件路径未正确配置**(引用[1]) 2. **MQTT库未正确集成到工程中** 3. **GN构建脚本语法错误**(如缺少逗号或括号) ### 解决方案 #### 步骤1:验证MQTT库路径 1. 确认`paho_mqtt`库已下载并放置在正确目录: ```bash # 标准目录结构参考 vendor/ └── hihope/ └── hispark_pegasus/ ├── demo/ │ └── 26_paho.mqtt.embedded-c/ # MQTT示例目录 └── third_party/ └── paho.mqtt.embedded-c/ # MQTT库源码 ``` 若缺失库文件,需从[官方仓库](https://github.com/eclipse/paho.mqtt.embedded-c)克隆: ```bash git clone https://github.com/eclipse/paho.mqtt.embedded-c vendor/third_party/paho.mqtt.embedded-c ``` #### 步骤2:修正GN构建脚本 在`demo/BUILD.gn`中(引用[3]): ```python lite_component("demo") { features = [ # 启用MQTT示例(移除行首#号) "26_paho.mqtt.embedded-c:app", ] } ``` 在`26_paho.mqtt.embedded-c/app.gn`中检查路径: ```python executable("app") { include_dirs = [ // 添加MQTT库头文件路径 "//vendor/third_party/paho.mqtt.embedded-c/MQTTPacket/src", "//vendor/third_party/paho.mqtt.embedded-c/MQTTClient-C/src", ] sources = [ "mqtt_demo.c", // 添加MQTT库源文件 "//vendor/third_party/paho.mqtt.embedded-c/MQTTPacket/src/*.c", "//vendor/third_party/paho.mqtt.embedded-c/MQTTClient-C/src/*.c" ] # 注意:路径分隔符使用正斜杠/,每行末尾加逗号 } ``` #### 步骤3:检查JSON配置 在`config.json`中确认MQTT组件已声明: ```json { "subsystem": "iot", "components": [ { "component": "paho_mqtt", "features": [] } ] } ``` #### 步骤4:编译验证 执行编译命令,观察输出: ```bash hb build -f ``` 若仍有路径错误,根据报错信息调整`include_dirs`和`sources`中的路径深度。 ### 关键检查点 1. **路径大小写敏感**:Linux系统严格区分大小写,确保`MQTTPacket`等名称拼写准确 2. **依赖库完整性**:检查`third_party/paho.mqtt.embedded-c`是否包含`src`目录 3. **GN语法验证**:所有数组元素以逗号结尾,字符串用双引号包裹(引用[1]) ### 注意事项 - 鸿蒙编译系统要求**绝对路径**(以`//`开头) - 若使用自定义路径,需在`build/lite/config/subsystem/iot.gni`中注册新路径 - 网络功能需提前配置WiFi连接(引用[3]中`19_wificonnect`示例) ### 相关问题 1. Hi3861开发中如何正确配置第三方库的GN构建脚本? 2. OpenHarmony编译出现`undefined reference to`错误应如何排查?[^1] 3. 如何为Hi3861移植新的物联网协议库(如CoAP)? 4. MQTT连接失败时有哪些调试手段? [^1]: 引用自站内文档《FS_Hi3861鸿蒙开发板编译问题排查》 [^2]: 引用自Hi3861芯片规格说明 [^3]: 引用自《Hi3861 OpenHarmony嵌入式应用入门》环境配置示例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值